@@ -1090,49 +1090,59 @@ AssociatedTypeInference::computeAbstractTypeWitness(
1090
1090
void AssociatedTypeInference::collectAbstractTypeWitnesses (
1091
1091
TypeWitnessSystem &system,
1092
1092
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) {
1097
1110
// FIXME: The RequirementMachine will assert on re-entrant construction.
1098
1111
// We should find a more principled way of breaking this cycle.
1099
1112
if (ctx.isRecursivelyConstructingRequirementMachine (
1100
1113
conformedProto->getGenericSignature ().getCanonicalSignature ()) ||
1101
1114
ctx.isRecursivelyConstructingRequirementMachine (conformedProto) ||
1102
1115
conformedProto->isComputingRequirementSignature ())
1103
- continue ;
1116
+ return ;
1104
1117
1105
1118
for (const auto &req :
1106
1119
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);
1112
1122
}
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);
1113
1134
}
1114
1135
1115
1136
// If the same-type constraints weren't enough to resolve an associated type,
1116
- // look for more options .
1137
+ // look for default type witnesses .
1117
1138
for (auto *const assocType : unresolvedAssocTypes) {
1118
- if (system.hasResolvedTypeWitness (assocType->getName ())) {
1139
+ if (system.hasResolvedTypeWitness (assocType->getName ()))
1119
1140
continue ;
1120
- }
1121
1141
1122
1142
// If we find a default type definition, feed it to the system.
1123
1143
if (const auto &typeWitness = computeDefaultTypeWitness (assocType)) {
1124
1144
system.addDefaultTypeWitness (typeWitness->getType (),
1125
1145
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
- }
1136
1146
}
1137
1147
}
1138
1148
}
0 commit comments