First, add some new utility methods to create SubstitutionMaps:
- GenericSignature::getSubstitutionMap() -- provides a new
way to directly build a SubstitutionMap. It takes a
TypeSubstitutionFn and LookupConformanceFn. This is
equivalent to first calling getSubstitutions() with the two
functions to create an ArrayRef<Substitution>, followed by
the old form of getSubstitutionMap() on the result.
- TypeBase::getContextSubstitutionMap() -- replacement for
getContextSubstitutions(), returning a SubstitutionMap.
- TypeBase::getMemberSubstitutionMap() -- replacement for
getMemberSubstitutions(), returning a SubstitutionMap.
With these in place, almost all existing uses of subst() taking
a ModuleDecl can now use the new form taking a SubstitutionMap
instead. The few remaining cases are explicitly written to use a
TypeSubstitutionFn and LookupConformanceFn.
Conformances for an associated type might be attached to any
same-named associated type of the parent, so search those as
well. Overally, this is a fairly expensive search, and there is likely
a better architectural solution that will require some refactoring of
SubstitutionMap.
When enumerating requirements, always use the archetype anchors to
express requirements. Unlike "representatives", which are simply there
to maintain the union-find data structure used to track equivalence
classes of potential archetypes, archetype anchors are the
ABI-stable canonical types within a fully-formed generic signature.
The test case churn comes from two places. First, while
representatives are *often* the same as the archetype anchors, they
aren't *always* the same. Where they differ, we'll see a change in
both the printed generic signature and, therefore, it's
mangling.
Additionally, requirement inference now takes much greater
care to make sure that the first types in the requirement follow
archetype anchor ordering, so actual conformance requirements occur in
the requirement list at the archetype anchor---not at the first type
that is equivalent to the anchor---which permits the simplification in
IRGen's emission of polymorphic arguments.
We were dropping the substitutions required to call the default
argument generator on the floor, when the correct solution is to
remap them to substitutions in terms of the base class signature.
Fixes <rdar://problem/29721571>.
Type substitution works on a fairly narrow set of types: generic type
parameters (to, e.g., use a generic) and archetypes (to map out of a
generic context). Historically, it was also used with
DependentMemberTypes, but recent refactoring to eliminate witness
markers eliminate that code path.
Therefore, narrow TypeSubstitutionMap's keys to SubstitutableType,
which covers archetypes and generic type parameters. NFC
The witnesses in a NormalProtocolConformance have never been
completely serialized, because their substitutions involved a weird
mix of archetypes that blew up the deserialization code. So, only the
witness declarations themselves got serialized. Many clients (the type
checker, SourceKit, etc.) didn't need the extra information, but some
clients (e.g., the SIL optimizers) would end up recomputing this
information. Ick.
Now, serialize the complete Witness structure along with the AST,
including information about the synthetic environment, complete
substitutions, etc. This should obsolete some redundant code paths in
the SIL optimization infrastructure.
This (de-)serialization code takes a new-ish approach to serializing
the synthetic environment in that it avoids serializing any
archetypes. Rather, it maps everything back to interface types during
serialization, and deserialization forms a new generic environment
(with new archetypes!) on-the-fly, mapping deserialized types back
into that environment (and to those archetypes). This way, we don't
have to maintain identity of archetypes in the deserialization code,
and might get some better re-use of the archetypes.
More of rdar://problem/24079818.