We want to delay the realization of potential archetypes as late as
possible; for layout constraints, push realization of potential archetypes
down past the point where we know whether we’re learning anything new
about the equivalence class.
No functionality change, yet.
Any potential archetype with the lowest depth in the equivalence class
will do when we're resolving for equivalence classes, so keep the
lowest-depth potential archetype handy.
Teach GenericSignatureBuilder::resolveEquivalenceClass() to perform
resolution of a type into a dependent type and its equivalence class
without realizing that potential archetype. Improves type-checking
time for the standard library by ~6%.
Now that the GenericSignatureBuilder is no longer sensitive to the input
module, stop uniquing the canonical GSBs based on that module. The main
win here is when deserializing a generic environment: we would end up
creating a canonical GSB in the module we deserialized and another
canonical GSB in the module in which it is used.
Implement a module-agnostic conformance lookup operation within the GSB
itself, so it does not need to be supplied by the code constructing the
generic signature builder. This makes the generic signature builder
(closer to) being module-agnostic.
Use the "override" information in associated type declarations to provide
AST-level access to the associated type "anchor", i.e., the canonical
associated type that will be used in generic signatures, mangling,
etc.
In the Generic Signature Builder, only build potential archetypes for
associated types that are anchors, which reduces the number of
potential archetypes we build when type-checking the standard library
by 14% and type-checking time for the standard library by 16%.
There's a minor regression here in some generic signatures that were
accidentally getting (correct) same-type constraints. There were
existing bugs in this area already (Huon found some of them), while
will be addressed as a follow-up.
Fies SR-5726, where we were failing to type-check due to missed
associated type constraints.
Once we compute a generic signature from a generic signature builder,
all queries involving that generic signature will go through a separate
(canonicalized) builder, and the original builder can no longer be used.
The canonicalization process then creates a new, effectively identical
generic signature builder. How silly.
Once we’ve computed the signature of a generic signature builder, “register”
it with the ASTContext, allowing us to move the existing generic signature
builder into place as the canonical generic signature builder. The builder
requires minimal patching but is otherwise fully usable.
Thanks to Slava Pestov for the idea!
This is somewhat of a pyrrhic victory, because it was just a shell over
resolvePotentialArchetype() anyway, but we now have fewer entry points that
produce potential archetypes.
We shouldn’t need a potential archetype to map an interface type to a
contextual type. Port `getTypeInContext()` over to `EquivalenceClass`,
largely unchanged, so we don’t directly form archetypes.
Kills a few more uses of `GenericSignatureBuilder::resolveArchetype()`.
The anchor of an equivalence class canonically represents that equivalence
class. Add API for computing the anchor directly, and switch a few more
clients off of `resolveArchetype()`.
The type checker shouldn’t know about potential archetypes. Use
GenericSignatureBuilder::resolveEquivalenceClass() and perform the lookup
into that instead.
The test case change highlights an existing problem with generic signature
minimization.
Funnel all places where we create a generic signature builder to compute
the generic signature through a single entry point in the GSB
(`computeGenericSignature()`), and make `finalize` and `getGenericSignature`
private so no new uses crop up.
Tighten up the signature of `computeGenericSignature()` so it only works on
GSB rvalues, and ensure that all clients consider the GSB dead after that
point by clearing out the internal representation of the GSB.
We had two similar loops that performed name lookup for nested types on a
potential archetype, so consolidate those into a single implementation on
the equivalence class itself.
Managing equivalence classes via the implicit structure of potential
archetypes is silly, and leads to weird patterns where we visit all
potential archetypes just to find the equivalence classes. Teach the
GSB implementation to manage equivalence classes in a linked list, so we
can easily iterate over them, and switch most uses of
`visitPotentialArchetypes()` over to that iteration.
The type checker shouldn’t know about potential archetypes. Use
GenericSignatureBuilder::resolveEquivalenceClass() and perform the lookup
into that instead.
The test case change highlights an existing problem with generic signature
minimization.
Funnel all places where we create a generic signature builder to compute
the generic signature through a single entry point in the GSB
(`computeGenericSignature()`), and make `finalize` and `getGenericSignature`
private so no new uses crop up.
Tighten up the signature of `computeGenericSignature()` so it only works on
GSB rvalues, and ensure that all clients consider the GSB dead after that
point by clearing out the internal representation of the GSB.
We had two similar loops that performed name lookup for nested types on a
potential archetype, so consolidate those into a single implementation on
the equivalence class itself.
Once we compute a generic signature from a generic signature builder,
all queries involving that generic signature will go through a separate
(canonicalized) builder, and the original builder can no longer be used.
The canonicalization process then creates a new, effectively identical
generic signature builder. How silly.
Once we’ve computed the signature of a generic signature builder, “register”
it with the ASTContext, allowing us to move the existing generic signature
builder into place as the canonical generic signature builder. The builder
requires minimal patching but is otherwise fully usable.
Thanks to Slava Pestov for the idea!
Funnel all places where we create a generic signature builder to compute
the generic signature through a single entry point in the GSB
(`computeGenericSignature()`), and make `finalize` and `getGenericSignature`
private so no new uses crop up.
Tighten up the signature of `computeGenericSignature()` so it only works on
GSB rvalues, and ensure that all clients consider the GSB dead after that
point by clearing out the internal representation of the GSB.
We had two similar loops that performed name lookup for nested types on a
potential archetype, so consolidate those into a single implementation on
the equivalence class itself.