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
allows the red-green system to do its change detection even if there is no
query key available for a given dep-node -- something which is needed for
handling trait selection because it is not based on queries.
## The Projection Query Pattern
It's interesting to note that `eval_always` and `no_hash` can be used together
in the so-called "projection query" pattern. It is often the case that there is
one query that depends on the entirety of the compiler's input (e.g. the indexed HIR)
and another query that projects individual values out of this monolithic value
(e.g. a HIR item with a certain `DefId`). These projection queries allow for
building change propagation "firewalls" because even if the result of the
monolithic query changes (which it is very likely to do) the small projections
can still mostly be marked as green.
```ignore
+------------+
| | +---------------+ +--------+
| | <---------| projection(x) | <---------| foo(a) |
| | +---------------+ +--------+