[NFC] Rework the internal design of SIL type lowering. #64099
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
The old, CRTP-based design was really difficult to understand because of how it tried to map type-based visitation into property-based handling. That didn't really work out for producing
TypeLowering
objects anyway, since a lot of different type kinds want their ownTypeLowering
handling even if they share abstract properties. That in turn led to a lot of redundancy between the two users, and that redundancy tended to lead to bugs --- I got into this because I kept finding problems where the pack-related types had different properties on different paths.That's bad enough, really, but there were other problems, too. Classification basically repeated the entire
AbstractionPattern
-based walk over the type that lowering does, and I'm not sure why --- there aren't actually any type properties that vary by abstraction pattern, and I'm not sure why there ever would be. Needing that abstraction pattern clutters up the API and implementation a lot, especially when working with lowered types. And the way that property computation was directly tied to producing aTypeLowering
object meant that preserving certain kinds of top-down property was unnecessarily cumbersome and error-prone. For example, the code was passing down a bit to remember that we'd looked through an opaque archetype so that it would get persisted in the is-expansion-sensitive bit; that's trivial to handle in the one case if property computation is independent. We also weren't set up to answer any of the basic lowering questions (type properties, lowered type) without vending aTypeLowering
object, which is just an unnecessary expense (and we probably ought to get rid of those objects completely someday).(The old design was entirely my fault, just to be clear here.)
Anyway, we can instead separate these into three related actions:
TypeLowering
objectEach of these operations is then relatively straightforward to implement and largely stands separate from the others. And we can make queries for lowered types and certain type properties answerable without getting a
TypeLowering
, although I have not changed any clients yet to stop asking for aTypeLowering
unnecessarily.I did have an initial design for type property computation which relied on being given a lowered type, but that was unnecessary, expensive, and caused problems with the infinite-type check.
I also removed the thing where type lowering would find generic signatures for interface substTypes in the abstraction pattern. This kind of idea is absolutely asking for trouble with confusion between generic signatures — the abstraction pattern is its own type, and the subst type is a sort of substitution of that which can be in terms of a different signature entirely. I suspect we've been getting away with it mostly because relatively little code actually needs to lower (or ask about the type properties of) interface types. Anyway, this required updating a few clients to use
GenericContextRAII
correctly, but the result is so much better and more obviously correct.Oh, and I added move-only-ness as a type property, although I'm not sure my logic is completely correct in the presence of stuff like
SILMoveOnlyWrappedType
.