@@ -1090,49 +1090,59 @@ AssociatedTypeInference::computeAbstractTypeWitness(
10901090void AssociatedTypeInference::collectAbstractTypeWitnesses (
10911091 TypeWitnessSystem &system,
10921092 ArrayRef<AssociatedTypeDecl *> unresolvedAssocTypes) const {
1093- // First, look at all the protocols the adoptee conforms to and feed the
1094- // same-type constraints in their requirement signatures to the system.
1095- for (auto *const conformedProto :
1096- dc->getSelfNominalTypeDecl ()->getAllProtocols (/* sorted=*/ true )) {
1093+ // Look for suitably-named generic parameters first, before we go digging
1094+ // through same-type requirements of protocols.
1095+ if (auto genericSig = dc->getGenericSignatureOfContext ()) {
1096+ for (auto *const assocType : unresolvedAssocTypes) {
1097+ for (auto *gp : genericSig.getInnermostGenericParams ()) {
1098+ // Packs cannot witness associated type requirements.
1099+ if (gp->isParameterPack ())
1100+ continue ;
1101+
1102+ if (gp->getName () == assocType->getName ()) {
1103+ system.addTypeWitness (assocType->getName (), gp);
1104+ }
1105+ }
1106+ }
1107+ }
1108+
1109+ auto considerProtocolRequirements = [&](ProtocolDecl *conformedProto) {
10971110 // FIXME: The RequirementMachine will assert on re-entrant construction.
10981111 // We should find a more principled way of breaking this cycle.
10991112 if (ctx.isRecursivelyConstructingRequirementMachine (
11001113 conformedProto->getGenericSignature ().getCanonicalSignature ()) ||
11011114 ctx.isRecursivelyConstructingRequirementMachine (conformedProto) ||
11021115 conformedProto->isComputingRequirementSignature ())
1103- continue ;
1116+ return ;
11041117
11051118 for (const auto &req :
11061119 conformedProto->getRequirementSignature ().getRequirements ()) {
1107- if (req.getKind () != RequirementKind::SameType) {
1108- continue ;
1109- }
1110-
1111- system.addSameTypeRequirement (req);
1120+ if (req.getKind () == RequirementKind::SameType)
1121+ system.addSameTypeRequirement (req);
11121122 }
1123+ };
1124+
1125+
1126+ // First, look at the conformed protocol for same-type requirements. These
1127+ // are less likely to cause request cycles.
1128+ considerProtocolRequirements (conformance->getProtocol ());
1129+
1130+ // Also look through all other protocols the conforming type conforms to.
1131+ for (auto *const conformedProto :
1132+ dc->getSelfNominalTypeDecl ()->getAllProtocols (/* sorted=*/ true )) {
1133+ considerProtocolRequirements (conformedProto);
11131134 }
11141135
11151136 // If the same-type constraints weren't enough to resolve an associated type,
1116- // look for more options .
1137+ // look for default type witnesses .
11171138 for (auto *const assocType : unresolvedAssocTypes) {
1118- if (system.hasResolvedTypeWitness (assocType->getName ())) {
1139+ if (system.hasResolvedTypeWitness (assocType->getName ()))
11191140 continue ;
1120- }
11211141
11221142 // If we find a default type definition, feed it to the system.
11231143 if (const auto &typeWitness = computeDefaultTypeWitness (assocType)) {
11241144 system.addDefaultTypeWitness (typeWitness->getType (),
11251145 typeWitness->getDefaultedAssocType ());
1126- } else {
1127- // As a last resort, look for a generic parameter that matches the name
1128- // of the associated type.
1129- if (auto genericSig = dc->getGenericSignatureOfContext ()) {
1130- for (auto *gp : genericSig.getInnermostGenericParams ()) {
1131- if (gp->getName () == assocType->getName ()) {
1132- system.addTypeWitness (assocType->getName (), gp);
1133- }
1134- }
1135- }
11361146 }
11371147 }
11381148}
0 commit comments