Description
Currently, there are a number of trait system operations that are used by the code in trans. Currently, they are invoked directly, and behind the scenes they use a DepTrackingMap
to memoize across multiple calls. It would be better for incremental if they were converted into named queries. Effectively the goal is to remove the trans_trait_caches
field of the tcx. For these particular operations, since they do not work on types that include inference variables, this should be fairly straight-forward:
trans_fulfill_obligation
, defined here, which immediately invokes thememoize
function here.- The associated type normalization that is cached here could also be invoking a (newly defined) query.
The idea would to take the following steps:
- Define a query for
trans_fulfill_obligation
.- Reference material on how to define a query can be found here.
- Reference material on how the Rust compiler represents types and what the
Ty<'tcx>
type is. - In this case, you will need to add an appropriate line to the list of queries, and then you will need to convert the existing
fn trans_fulfill_obligation
from a method (as it is currently defined) into a free-standing function that serves as a provider. You can just remove the call tomemoize
, which would no longer be needed. - The trait system already defines a number of queries; those providers are linked here, so you could pick one of those to use as a rough model for what bits go where (e.g., the
specialization_graph_of
query).
- With respect to the normalization that is taking place here, I think a wee bit of refactoring is in order before we introduce the query. The actual setup here is a bit confused and probably could use even more refactoring, but for the purposes of this issue, we can do something fairly tailored.
- Step 1: Rename the method
normalize_associated_type()
tonormalize_associated_type_in()
. This method is defined here. It only has a handful of callers (as you can see with a quickrg \.normalize_associated_type\(
).- This is a generic function that will normalize associated types in all kinds of things.
- Step 2: Define a query
normalize_ty(Ty<'tcx>) -> Ty<'tcx>
that simply invokesnormalize_associated_types_in
. This is basically that function in query form, but specialized to inputs of typeTy<'tcx>
. - Step 3. Replace these lines that invoke
memoize()
) with code that just invokes the queryself.tcx.normalize_ty(ty)
.
- Step 1: Rename the method
For bonus points, we might consider converting the following functions into queries. It seems like they could benefit from caching:
traits::get_vtable_methods
(definition)- would have to be converted to return a vector
traits::normalize_and_test_predicates
trans_normalize
trans_apply_param_substs
It's unclear though if this is a good idea. I'd keep those for a later PR so we can do some experiments with performance and memory use.