Commit Graph

170 Commits

Author SHA1 Message Date
John Kåre Alsaker 6442b48dee Add more robust handling of nested query cycles 2026-04-12 14:38:43 +02:00
John Kåre Alsaker 690d1938a7 Break a single query cycle in the deadlock handler 2026-04-08 20:43:31 +02:00
Nicholas Nethercote 15c6e6e092 Add a handle_cycle_error query modifier.
This modifier indicates that a query has a custom handler for cycles.
That custom handler must be found at
`rustc_query_impl::handle_cycle_error::$name`.

This eliminates the need for `specialize_query_vtables`, which is the
current hack to install custom handlers. It's more lines of code in
total, but indicating special treatment of a query via a modifier in
`queries.rs` is more consistent with how other aspects of queries are
handled.
2026-04-03 13:44:12 +11:00
Jacob Pratt 39343f53fd Rollup merge of #154252 - Zalathar:on-disk-cache, r=nnethercote
Don't store current-session side effects in `OnDiskCache`

This PR is a series of related cleanups to `OnDiskCache`, which is responsible for loading query return values (and side effects) that were serialized during the previous incremental-compilation session.

The primary change is to move the `current_side_effects` field out of OnDiskCache and into QuerySystem. That field was awkward because it was the only part of OnDiskCache state related to serializing the *current* compilation session, rather than loading values from the previous session.

The other commits should hopefully be straightforward.

r? nnethercote (or compiler)
2026-03-23 23:42:51 -04:00
Zalathar afffa7d6e3 Don't store current-session side effects in OnDiskCache
Every other part of `OnDiskCache` deals with loading information from the
_previous_ session, except for this one field.

Moving it out to `QuerySystem` makes more sense, because that's also where
query return values are stored (inside the caches in their vtables).
2026-03-24 12:56:51 +11:00
Nicholas Nethercote 90ea993083 Rename various query cycle things.
The existing names have bugged me for a while. Changes:

- `CycleError` -> `Cycle`. Because we normally use "error" for a `Diag`
  with `Level::Error`, and this type is just a precursor to that. Also,
  many existing locals of this type are already named `cycle`.

- `CycleError::cycle` -> `Cycle::frames`. Because it is a sequence of
  frames, and we want to avoid `Cycle::cycle` (and `cycle.cycle`).

- `cycle_error` -> `find_and_handle_cycle`. Because that's what it does.
  The existing name is just a non-descript noun phrase.

- `mk_cycle` -> `handle_cycle`. Because it doesn't make the cycle; the
  cycle is already made. It handles the cycle, which involves (a)
  creating the error, and (b) handling the error.

- `report_cycle` -> `create_cycle_error`. Because that's what it does:
  creates the cycle error (i.e. the `Diag`).

- `value_from_cycle_error` -> `handle_cycle_error_fn`. Because most
  cases don't produce a value, they just emit an error and quit.
  And the `_fn` suffix is for consistency with other vtable fns.

- `from_cycle_error` -> `handle_cycle_error`. A similar story for this
  module.
2026-03-24 08:47:34 +11:00
Stuart Cook b8cdd7a1c7 Rollup merge of #153942 - Zalathar:imports, r=nnethercote
Re-export `rustc_middle::query::{QuerySystem, QueryVTable}`

- Follow-up to https://github.com/rust-lang/rust/pull/153760#discussion_r2928848418.
---

All of the other public items in `rustc_middle::query::plumbing` are re-exported from `query`, except for these two, for no particular reason that I can see.

Re-exporting them allows `rustc_middle::query::plumbing` to have its visibility reduced to pub(crate).

Imports within `rustc_middle` have also been updated to consistently use the re-exports in `crate::query`.

r? nnethercote
2026-03-16 18:22:57 +11:00
Zalathar aa223a0220 Re-export rustc_middle::query::{QuerySystem, QueryVTable}
All of the other public items in `rustc_middle::query::plumbing` are
re-exported from `query`, except for these two, for no particular reason that I
can see.

Re-exporting them allows `rustc_middle::query::plumbing` to have its visibility
reduced to pub(crate).

Imports within `rustc_middle` have also been updated to consistently use the
re-exports in `crate::query`.
2026-03-16 18:20:35 +11:00
Nicholas Nethercote b41b0c494c Rename all-query functions.
There are four functions that use `for_each_query_vtable!` to call an "inner"
function. They are:

- collect_active_jobs_from_all_queries -> gather_active_jobs
- alloc_self_profile_query_strings -> alloc_self_profile_query_strings_for_query_cache
- encode_all_query_results -> encode_query_results
- query_key_hash_verify_all -> query_key_hash_verify

These names are all over the place. This commit renames them as follows:

- collect_active_query_jobs{,_inner}
- alloc_self_profile_query_strings{,_inner}
- encode_query_values{,_inner}
- verify_query_key_hashes{,_inner}

This:
- puts the verb at the start
- uses "inner" for all the inners (which makes sense now that the inners are
  all next to their callers)
- uses `_query_` consistently
- avoids `all`, because the plurals are enough
- uses `values` instead of `results`
- removes the `collect`/`gather` distinction, which is no longer
  important
2026-03-16 16:33:40 +11:00
Zalathar 6699c13683 Move the big rustc_query_impl macro into a physical query_impl.rs
Moving the macro and its expansion into the same physical file resolves a lot
of tension in the current module arrangement.

Code in the macro is now free to use plain imports in the same file, and there
is no longer any question of whether `mod query_impl` should be declared inside
the macro, or surrounding a separate expansion site.
2026-03-14 15:41:00 +11:00
Nicholas Nethercote 834b7e7e43 Streamline active job collection.
`collect_active_jobs_from_all_queries` takes a `require_complete` bool,
and then some callers `expect` a full map result while others allow a
partial map result. The end result is four possible combinations, but
only three of them are used/make sense.

This commit introduces `CollectActiveJobsKind`, a three-value enum that
describes the three sensible combinations, and rewrites
`collect_active_jobs_from_all_queries` around it. This makes it and its
call sites much clearer, and removes the weird `Option<()>` and
`Result<QueryJobMap, QueryJobMap>` return types.

Other changes of note.
- `active` is removed. The comment about `make_frame` is out of date,
  and `create_deferred_query_stack_frame` *is* safe to call with the
  query state locked.
- When shard locking failure is allowed, collection no longer stops on
  the first failed shard.
2026-03-13 21:57:59 +11:00
John Kåre Alsaker 85967c4de4 Add a TaggedQueryKey to identify a query instance 2026-03-13 07:49:38 +01:00
Zalathar 0059012ab2 Introduce for_each_query_vtable! to move more code out of query macros 2026-03-11 22:18:00 +11:00
Daria Sukhonina b707e7ae52 Remove FromCycleError trait before code formatting
Currently `QueryVTable`'s `value_from_cycle_error` function pointer uses the `FromCycleError` trait to call query cycle handling code and to construct an erroneous query output value.
This trick however relies too heavily on trait impl specialization and makes those impls inconsistent (which is bad AFAIK).
Instead this commit directly modifies `value_from_cycle_error` function pointer upon vtable initialization and gets rid of `FromCycleError`.
2026-03-10 15:13:47 +03:00
Zalathar 0a369a799f Replace the try_mark_green hook with direct calls to tcx.dep_graph
All of the existing call sites are directly touching `tcx.dep_graph` anyway, so
the extra layer of indirection provides no real benefit.
2026-03-08 21:53:13 +11:00
Nicholas Nethercote 5677f7c706 Rename trait Value as FromCycleError.
`Value` is an unhelpfully generic name. Standard naming procedure for a
trait with a single method is for the trait name to match the method
name, which is what this commit does. Likewise, the enclosing module is
renamed from `values` to `from_cycle_error`.

Also add a comment about some non-obvious behaviour.
2026-03-02 14:26:58 +11:00
Nicholas Nethercote 90abedee9c Remove ENCODE_QUERY_RESULTS.
And also `encode_query_results` for each cacheable query. This is done
by generating `encode_all_query_results` and having it do things more
directly.
2026-02-27 08:03:04 +11:00
Nicholas Nethercote 7323750309 Remove ALLOC_SELF_PROFILE_QUERY_STRINGS.
And also `alloc_self_profile_query_strings` for each query. This is done
by generating the top-level `alloc_self_profile_query_strings` and
having it do things more directly.
2026-02-27 07:57:39 +11:00
Nicholas Nethercote 6b0beecd95 Remove PER_QUERY_GATHER_ACTIVE_JOBS_FNS.
And also `gather_active_jobs` for each query. This is done by generating
`collect_active_jobs_from_all_queries` and having it do things more
directly.
2026-02-27 07:55:47 +11:00
Nicholas Nethercote 8f0ca1d253 Remove QUERY_KEY_HASH_VERIFY.
And also `query_key_hash_verify` for each query. This is done by
generating `query_key_hash_verify_all` and having it do things more
directly.
2026-02-27 07:19:19 +11:00
Nicholas Nethercote fbea6ddcd2 Rename trait Key as trait QueryKey`
Because `Key` is extremely generic and hard to search for.

Also rename `LocalKey` and `AsLocalKey` similarly, for consistency.
2026-02-26 19:18:48 +11:00
Nicholas Nethercote 608d85f989 Move two functions into hooks.
`QuerySystem` has two function pointers: `encode_query_results` and
`try_mark_green`. These exist so that `rustc_middle` can call functions
from upstream crates.

But we have a more general mechanism for that: hooks. So this commit
converts these two cases into hooks.
2026-02-25 17:30:47 +11:00
Nicholas Nethercote b76b26db3b Remove QuerySystemFns.
It has a single use and doesn't provide any real value. Removing it
allows the removal of two `for<'tcx>` qualifiers.
2026-02-25 17:30:17 +11:00
Nicholas Nethercote 2bc5167e99 Merge QueryEngine into QueryVTable.
`QueryEngine` is a struct with one function pointer per query. This
commit removes it by moving each function pointer into the relevant
query's vtable, which is already a collection of function pointers for
that query. This makes things simpler.
2026-02-25 08:26:27 +11:00
Nicholas Nethercote e45224c4af Improve how QueryCaches and QueryStates are stored.
`QuerySystem` has these fields:
```
pub states: QueryStates<'tcx>,
pub caches: QueryCaches<'tcx>,
pub query_vtables: PerQueryVTables<'tcx>,
```
Each one has an entry for each query.

Some methods that take a query-specific `QueryVTable` need to access the
corresponding query-specific states and/or caches. So `QueryVTable`
stores the *byte offset* to the relevant fields within `states` and
`caches`, and uses that to (with `unsafe`) access the fields. This is
bizarre, and I hope it made sense in the past when the code was
structured differently.

This commit moves `QueryState` and `QueryCache` inside `QueryVTable`. As
a result, the query-specific states and/or caches are directly
accessible, and no unsafe offset computations are required. Much simpler
and more normal. Also, `QueryCaches` and `QueryStates` are no longer
needed, which makes `define_callbacks!` a bit simpler.

The commit also rename the fields and their getters to `states` and
`caches`.
2026-02-25 08:13:56 +11:00
Zalathar 16fbd29fcf Streamline QueryVTableUnerased into GetQueryVTable 2026-02-24 15:29:19 +11:00
Nicholas Nethercote 5aebfd648b Rename query_dispatcher and reduce its use.
It's now `query_vtable` because its return type changed. And thanks to
the previous commit it can be manually inlined in several places. (The
only remaining calls to it are in `make_dep_kind_vtable_for_query`,
which are more challenging to remove.)
2026-02-23 07:20:24 +11:00
Nicholas Nethercote 6c12694b64 Remove SemiDynamicQueryDispatcher and QueryFlags.
`SemiDynamicQueryDispatcher` is just a `QueryVTable` wrapper with an
additional `const FLAGS: QueryFlags` generic parameter that contains
three booleans. This arrangement exists as a performance optimization.
But the performance effects are very small and it adds quite a bit of
complexity to an already overly-complex part of the codebase. If it
didn't exist and somebody proposed adding it and asked me to review, I
almost certainly wouldn't approve it.

This commit removes it. The three booleans in `QueryFlags` are moved
into `QueryVTable` The non-trivial methods of
`SemiDynamicQueryDispatcher` become methods of `QueryVTable`.
2026-02-23 07:20:21 +11:00
Nicholas Nethercote baa74a85ee Remove DepKind name plumbing.
There is a bunch of plumbing to record the string `"foo"` for each
variant `DepKind::foo`. But that's what the `Debug `impl` now produces.
So this commit removes the plumbing.
2026-02-19 09:05:39 +11:00
Zalathar db58395a6b Don't use HasDepContext in DepGraph::with_task
The need for a `HasDepContext` impl on tuples can be avoided by passing the
query vtable as part of an argument tuple instead.
2026-02-17 17:30:55 +11:00
Zalathar fbb34d8c75 Remove wrapper struct QueryCtxt
This struct was only wrapping `TyCtxt` in order to implement traits that
were removed by RUST-152636.

This commit also slightly simplifies the signature of `execute_job_incr`, by
having it call `tcx.dep_graph.data()` internally.
2026-02-17 17:30:55 +11:00
Nicholas Nethercote ed091aaf5d Move rustc_query_system::query::dep_graph to rustc_middle.
Most of the files within the `dep_graph` module can be moved wholesale
into `rustc_middle`. But two of them (`mod.rs` and `dep_node.rs`) have
the same name as existing files in `rustc_middle`, so for those I just
copied the contents into the existing files.

The commit also moves `QueryContext` and `incremental_verify_ich*`
because they are tightly intertwined with the dep graph code. And a
couple of error structs moved as well.
2026-02-14 18:46:05 +11:00
Nicholas Nethercote fa3b046aa5 Move QueryMode.
From `rustc_query_system::query::plumbing` to
`rustc_middle::query::plumbing`.
2026-02-14 18:38:33 +11:00
Nicholas Nethercote 924dbc46d9 Move CycleErrorHandling.
From `rustc_query_system` to `rustc_middle`.
2026-02-14 18:38:33 +11:00
Nicholas Nethercote 940f30792c Move rustc_query_system::query::caches to rustc_middle::query.
This one is straightforward.
2026-02-14 18:38:30 +11:00
Nicholas Nethercote 8b0dc1ece0 Move rustc_query_system::query::job to rustc_middle.
This includes the types `QueryInfo`, `QueryJob`, `QueryJobId`,
`QueryWaiter`, `QueryLatch`, and `QueryLatchInfo`.

`CycleError` and `QueryStack*` had to come along too, due to type
interdependencies. The `QueryStack*` types are put into a new submodule
`rustc_middle::query::stack`.
2026-02-14 18:33:13 +11:00
Nicholas Nethercote 1ac199af0a Move QueryState/ActiveKeyStatus.
From `rustc_query_state` to `rustc_middle`.
2026-02-14 18:24:47 +11:00
Zalathar 1d6ef95075 Extract DepKindVTable constructors to their own module 2026-02-13 23:19:20 +11:00
Zalathar b9b28ba1b5 Collect active query jobs into struct QueryJobMap 2026-02-13 01:18:24 +11:00
Jacob Pratt 0e746d0a25 Rollup merge of #152434 - Zalathar:call-query, r=nnethercote
Clarify names of `QueryVTable` functions for "executing" a query

In the query system, there are several layers of functions involved in “executing” a query, with very different responsibilities at each layer, making it important to be able to tell them apart.

This PR renames two of the function pointers in `QueryVTable`, along with their associated helper functions, to hopefully do a better job of indicating what their actual responsibilities are.

r? nnethercote
2026-02-12 00:41:08 -05:00
Zalathar 0de45db240 Clarify names of QueryVTable functions for "executing" a query
This also changes the signature of `call_query_method` to not return a value,
because its only caller immediately discards the value anyway.
2026-02-11 16:50:10 +11:00
Nicholas Nethercote 923de04f6a Move rustc_middle::query::values to rustc_query_impl.
Because all uses are now in `rustc_query_impl`. This was made possible
by the previous commit. Less code in `rustc_middle`, hooray.
2026-02-10 18:46:05 +11:00
Nicholas Nethercote 066a935b0c Move parts of rustc_query_system::query::job to rustc_middle::job.
The latter is a new module.

As well as the code motion, some other changes were required.
- `QueryJobId` methods became free functions so they could move while
  `QueryJobId` itself stayed put. This was so `QueryMap` and
  `QueryJobInfo` could be moved.
- Some visibilities in `rustc_query_system` required changing.
- `collect_active_jobs_from_all_queries` is no longer required in `trait
  QueryContext`.
2026-02-10 16:59:33 +11:00
Nicholas Nethercote f9958048e0 Move HashResult.
It's the only thing left in `rustc_query_system::query::dispatcher`.
2026-02-09 20:02:43 +11:00
Nicholas Nethercote 541d7fc19d Remove trait QueryDispatcher.
It existed only to bridge the divide between `rustc_query_system` and
`rustc_query_impl`. But enough pieces have been moved from the former to
the latter that the trait is no longer needed. Less indirection and
abstraction makes the code easier to understand.
2026-02-09 20:02:41 +11:00
Nicholas Nethercote 52caa7ae6d Remove QueryDispatcherUnerased::Dispatcher associated type.
It's always `SemiDynamicQueryDispatcher`, so we can just use that type
directly. (This requires adding some explicit generic params to
`QueryDispatcherUnerased`.) Less indirection makes the code clearer, and
this is a prerequisite for the next commit, which is a much bigger
simplification.
2026-02-09 11:03:43 +11:00
Nicholas Nethercote d3d4fd9312 Tweak query key trait bounds.
Query keys must be stably hashable. Currently this requirement is
expressed as a where-clause on `impl QueryDispatcher for
SemiDynamicQueryDispatcher` and a where-clause on
`create_deferred_query_stack_frame`.

This commit removes those where-clause bounds and adds a single bound to
`QueryCache::Key`, which already has some other bounds. I.e. it
consolidates the bounds. It also gives them a name (`QueryCacheKey`) to
avoid repeating them. There is also a related `Key` trait in
`rustc_middle`; it should probably be merged with `QueryCacheKey` in the
future, but not today.

This cleanup helps with the next two commits, which do bigger
rearrangements, and where the where-clauses caused me some difficulties.
2026-02-09 10:23:44 +11:00
Nicholas Nethercote 6527b3404c Move a lot of rustc_query_system::plumbing to rustc_query_impl::execution (part 1).
[Note: this commit conceptually moves 75% of a file to another location,
and leaves 25% of it behind. It's impossible to preserve all the git
history. To preserve git history of the moved 75%, in this commit we
rename the file and remove the 25% from it, leaving the code in an
incomplete (uncompilable) state. In the next commit we add back the
25% in the old location.]

We are in the process of eliminating `rustc_query_system`. Chunks of it
are unused by `rustc_middle`, and so can be moved into
`rustc_query_impl`. This commit does some of that.

Mostly it's just moving code from one file to a new file. There are a
couple of non-trivial changes.

- `QueryState` and `ActiveKeyStatus` must remain in `rustc_query_system`
  because they are used by `rustc_middle`. But their inherent methods
  are not used by `rustc_middle`. So these methods are moved and
  converted to free functions.

- The visibility of some things must increase. This includes `DepGraphData`
  and some of its methods, which are now used in `rustc_query_impl`.
  This is a bit annoying but seems hard to avoid.

What little is left behind in
`compiler/rustc_query_system/src/query/plumbing.rs` will be able to
moved into `rustc_query_impl` or `rustc_middle` in the future.
2026-02-08 17:01:10 +11:00
Jonathan Brouwer cf2ea13042 Rollup merge of #152023 - nnethercote:rm-Value, r=nnethercote
Some `rustc_query_system` cleanups

Small improvements I found while looking closely at `rustc_query_system`. Best reviewed one commit at a time.

r? @cjgillot
2026-02-05 08:32:46 +01:00
Nicholas Nethercote 0932068b6c Move the QueryOverflow and QueryOverflowNote errors.
They are defined in `rustc_query_system` but used in `rustc_query_impl`.
This is very much *not* how things are supposed to be done; I suspect
someone got lazy and took a shortcut at some point.

This commit moves the errors into `rustc_query_impl`. This requires more
lines of code to give `rustc_query_impl` an errors module, but it's
worthwhile to do things in the normal way instead of a weird exceptional
way.
2026-02-05 09:29:46 +11:00