Home Explore Blog CI



rustc

8th chunk of `src/queries/incremental-compilation-in-detail.md`
ab01f72a0146654a81d8ad2bd4d175110a2ab5c5b44abc320000000100000ccc
The query system allows for applying [modifiers][mod] to queries. These
modifiers affect certain aspects of how the system treats the query with
respect to incremental compilation:

 - `eval_always` - A query with the `eval_always` attribute is re-executed
   unconditionally during incremental compilation. I.e. the system will not
   even try to mark the query's dep-node as green. This attribute has two use
   cases:

    - `eval_always` queries can read inputs (from files, global state, etc).
      They can also produce side effects like writing to files and changing global state.

    - Some queries are very likely to be re-evaluated because their result
      depends on the entire source code. In this case `eval_always` can be used
      as an optimization because the system can skip recording dependencies in
      the first place.

 - `no_hash` - Applying `no_hash` to a query tells the system to not compute
   the fingerprint of the query's result. This has two consequences:

    - Not computing the fingerprint can save quite a bit of time because
      fingerprinting is expensive, especially for large, complex values.

    - Without the fingerprint, the system has to unconditionally assume that
      the result of the query has changed. As a consequence anything depending
      on a `no_hash` query will always be re-executed.

   Using `no_hash` for a query can make sense in two circumstances:

    - If the result of the query is very likely to change whenever one of its
      inputs changes, e.g. a function like `|a, b, c| -> (a * b * c)`. In such
      a case recomputing the query will always yield a red node if one of the
      inputs is red so we can spare us the trouble and default to red immediately.
      A counter example would be a function like `|a| -> (a == 42)` where the
      result does not change for most changes of `a`.

    - If the result of a query is a big, monolithic collection (e.g. `index_hir`)
      and there are "projection queries" reading from that collection
      (e.g. `hir_owner`). In such a case the big collection will likely fulfill the
      condition above (any changed input means recomputing the whole collection)
      and the results of the projection queries will be hashed anyway. If we also
      hashed the collection query it would mean that we effectively hash the same
      data twice: once when hashing the collection and another time when hashing all
      the projection query results. `no_hash` allows us to avoid that redundancy
      and the projection queries act as a "firewall", shielding their dependents
      from the unconditionally red `no_hash` node.

 - `cache_on_disk_if` - This attribute is what determines which query results
   are persisted in the incremental compilation query result cache. The
   attribute takes an expression that allows per query invocation
   decisions. For example, it makes no sense to store values from upstream
   crates in the cache because they are already available in the upstream
   crate's metadata.

 - `anon` - This attribute makes the system use "anonymous" dep-nodes for the
   given query. An anonymous dep-node is not identified by the corresponding
   query key, instead its ID is computed from the IDs of its dependencies. This

Title: Query Modifiers: eval_always, no_hash, cache_on_disk_if, and anon
Summary
The query system uses modifiers to control query behavior during incremental compilation. `eval_always` forces unconditional re-execution and is suitable for queries with side effects or those highly dependent on the entire source code. `no_hash` skips fingerprint computation, assuming the result always changes, which is useful for functions sensitive to input changes or large collections with projection queries. `cache_on_disk_if` determines which query results are persisted in the cache, and `anon` makes the system use "anonymous" dep-nodes.