@@ -1669,32 +1669,39 @@ bool irgen::hasPolymorphicParameters(CanSILFunctionType ty) {
1669
1669
}
1670
1670
}
1671
1671
1672
- // / Emit a polymorphic parameters clause, binding all the metadata necessary.
1673
- void EmitPolymorphicParameters::emit (Explosion &in,
1674
- WitnessMetadata *witnessMetadata,
1675
- const GetParameterFn &getParameter) {
1676
- // Collect any early sources and bind local type data from them.
1677
- for (const Source &source : getSources ()) {
1678
- bindExtraSource (source, in, witnessMetadata);
1679
- }
1672
+ static
1673
+ void addPotentialArchetypeAccessPath (IRGenFunction &IGF,
1674
+ CanType targetDepType,
1675
+ CanType sourceDepType,
1676
+ GetTypeParameterInContextFn getInContext) {
1677
+ assert (targetDepType->isTypeParameter ());
1678
+ assert (sourceDepType->isTypeParameter ());
1680
1679
1681
- // Collect any concrete type metadata that's been passed separately.
1682
- enumerateUnfulfilledRequirements ([&](GenericRequirement requirement) {
1683
- auto value = in.claimNext ();
1684
- bindGenericRequirement (IGF, requirement, value,
1685
- [&](CanType type) { return getTypeInContext (type);});
1686
- });
1680
+ // We can only break down an associated-type path.
1681
+ auto sourceDepMemberType = dyn_cast<DependentMemberType>(sourceDepType);
1682
+ if (!sourceDepMemberType) return ;
1687
1683
1688
- // Bind all the fulfillments we can from the formal parameters.
1689
- bindParameterSources (getParameter);
1684
+ // We only really need to do this when there's a non-trivial set of
1685
+ // conformances, but we can't determine that just from this decl:
1686
+ // the associated type might gain conformances in a refining protocol.
1687
+ auto association = sourceDepMemberType->getAssocType ();
1690
1688
1691
- // Bind all the archetype access paths.
1692
- bindArchetypeAccessPaths ();
1693
- }
1689
+ // These can end up as non-archetypes because of multiple levels of
1690
+ // equality.
1691
+ auto destArchetype =
1692
+ dyn_cast<ArchetypeType>(getInContext (targetDepType));
1693
+ if (!destArchetype) return ;
1694
+ auto srcBaseArchetype =
1695
+ dyn_cast<ArchetypeType>(getInContext (sourceDepMemberType.getBase ()));
1696
+ if (!srcBaseArchetype) return ;
1694
1697
1695
- void EmitPolymorphicParameters::bindArchetypeAccessPaths () {
1696
- if (!Generics) return ;
1698
+ IGF.addArchetypeAccessPath (destArchetype,
1699
+ {srcBaseArchetype, association});
1700
+ }
1697
1701
1702
+ static void bindArchetypeAccessPaths (IRGenFunction &IGF,
1703
+ GenericSignature *Generics,
1704
+ GetTypeParameterInContextFn getInContext) {
1698
1705
// Remember all the extra ways we have of reaching the parameter
1699
1706
// archetypes due to type equality constraints.
1700
1707
for (auto reqt : Generics->getRequirements ()) {
@@ -1710,36 +1717,37 @@ void EmitPolymorphicParameters::bindArchetypeAccessPaths() {
1710
1717
auto firstType = reqt.getFirstType ()->getCanonicalType ();
1711
1718
auto secondType = reqt.getSecondType ()->getCanonicalType ();
1712
1719
1713
- addPotentialArchetypeAccessPath (firstType, secondType);
1714
- addPotentialArchetypeAccessPath (secondType, firstType);
1720
+ addPotentialArchetypeAccessPath (IGF, firstType, secondType, getInContext );
1721
+ addPotentialArchetypeAccessPath (IGF, secondType, firstType, getInContext );
1715
1722
}
1716
1723
}
1717
1724
1718
- void EmitPolymorphicParameters::
1719
- addPotentialArchetypeAccessPath (CanType targetDepType, CanType sourceDepType) {
1720
- assert (targetDepType->isTypeParameter ());
1721
- assert (sourceDepType->isTypeParameter ());
1722
-
1723
- // We can only break down an associated-type path.
1724
- auto sourceDepMemberType = dyn_cast<DependentMemberType>(sourceDepType);
1725
- if (!sourceDepMemberType) return ;
1725
+ // / Emit a polymorphic parameters clause, binding all the metadata necessary.
1726
+ void EmitPolymorphicParameters::emit (Explosion &in,
1727
+ WitnessMetadata *witnessMetadata,
1728
+ const GetParameterFn &getParameter) {
1729
+ // Collect any early sources and bind local type data from them.
1730
+ for (const Source &source : getSources ()) {
1731
+ bindExtraSource (source, in, witnessMetadata);
1732
+ }
1733
+
1734
+ auto getInContext = [&](CanType type) -> CanType {
1735
+ return getTypeInContext (type);
1736
+ };
1726
1737
1727
- // We only really need to do this when there's a non-trivial set of
1728
- // conformances, but we can't determine that just from this decl:
1729
- // the associated type might gain conformances in a refining protocol.
1730
- auto association = sourceDepMemberType->getAssocType ();
1738
+ // Collect any concrete type metadata that's been passed separately.
1739
+ enumerateUnfulfilledRequirements ([&](GenericRequirement requirement) {
1740
+ auto value = in.claimNext ();
1741
+ bindGenericRequirement (IGF, requirement, value, getInContext);
1742
+ });
1731
1743
1732
- // These can end up as non-archetypes because of multiple levels of
1733
- // equality.
1734
- auto destArchetype =
1735
- dyn_cast<ArchetypeType>(getTypeInContext (targetDepType));
1736
- if (!destArchetype) return ;
1737
- auto srcBaseArchetype =
1738
- dyn_cast<ArchetypeType>(getTypeInContext (sourceDepMemberType.getBase ()));
1739
- if (!srcBaseArchetype) return ;
1744
+ // Bind all the fulfillments we can from the formal parameters.
1745
+ bindParameterSources (getParameter);
1740
1746
1741
- IGF.addArchetypeAccessPath (destArchetype,
1742
- {srcBaseArchetype, association});
1747
+ if (!Generics) return ;
1748
+
1749
+ // Bind all the archetype access paths.
1750
+ bindArchetypeAccessPaths (IGF, Generics, getInContext);
1743
1751
}
1744
1752
1745
1753
void IRGenFunction::addArchetypeAccessPath (CanArchetypeType targetArchetype,
@@ -2507,6 +2515,12 @@ void GenericTypeRequirements::bindFromBuffer(IRGenFunction &IGF,
2507
2515
Address buffer,
2508
2516
GetTypeParameterInContextFn getInContext) {
2509
2517
bindFromGenericRequirementsBuffer (IGF, Requirements, buffer, getInContext);
2518
+
2519
+ auto Generics = TheDecl->getGenericSignature ();
2520
+ if (!Generics) return ;
2521
+
2522
+ // Bind all the archetype access paths in the signature's requirements.
2523
+ bindArchetypeAccessPaths (IGF, Generics, getInContext);
2510
2524
}
2511
2525
2512
2526
void irgen::bindFromGenericRequirementsBuffer (IRGenFunction &IGF,
0 commit comments