@@ -798,7 +798,56 @@ AssociatedTypeDecl *AssociatedTypeInference::findDefaultedAssociatedType(
798798 return results.size () == 1 ? results.front () : nullptr ;
799799}
800800
801- Optional<std::pair<AssociatedTypeDecl *, Type>>
801+ Type AssociatedTypeInference::computeFixedTypeWitness (
802+ AssociatedTypeDecl *assocType) {
803+ Type resultType;
804+
805+ // Look at all of the inherited protocols to determine whether they
806+ // require a fixed type for this associated type.
807+ for (auto conformedProto : adoptee->getAnyNominal ()->getAllProtocols ()) {
808+ if (conformedProto != assocType->getProtocol () &&
809+ !conformedProto->inheritsFrom (assocType->getProtocol ()))
810+ continue ;
811+
812+ auto sig = conformedProto->getGenericSignature ();
813+
814+ // FIXME: The RequirementMachine will assert on re-entrant construction.
815+ // We should find a more principled way of breaking this cycle.
816+ if (ctx.isRecursivelyConstructingRequirementMachine (sig.getCanonicalSignature ()) ||
817+ ctx.isRecursivelyConstructingRequirementMachine (conformedProto) ||
818+ conformedProto->isComputingRequirementSignature ())
819+ continue ;
820+
821+ auto selfTy = conformedProto->getSelfInterfaceType ();
822+ if (!sig->requiresProtocol (selfTy, assocType->getProtocol ()))
823+ continue ;
824+
825+ auto structuralTy = DependentMemberType::get (selfTy, assocType->getName ());
826+ const auto ty = sig.getCanonicalTypeInContext (structuralTy);
827+
828+ // A dependent member type with an identical base and name indicates that
829+ // the protocol does not same-type constrain it in any way; move on to
830+ // the next protocol.
831+ if (auto *const memberTy = ty->getAs <DependentMemberType>()) {
832+ if (memberTy->getBase ()->isEqual (selfTy) &&
833+ memberTy->getName () == assocType->getName ())
834+ continue ;
835+ }
836+
837+ if (!resultType) {
838+ resultType = ty;
839+ continue ;
840+ }
841+
842+ // FIXME: Bailing out on ambiguity.
843+ if (!resultType->isEqual (ty))
844+ return Type ();
845+ }
846+
847+ return resultType;
848+ }
849+
850+ Optional<AbstractTypeWitness>
802851AssociatedTypeInference::computeDefaultTypeWitness (
803852 AssociatedTypeDecl *assocType) const {
804853 // Go find a default definition.
@@ -814,7 +863,7 @@ AssociatedTypeInference::computeDefaultTypeWitness(
814863 if (defaultType->hasError ())
815864 return None;
816865
817- return std::make_pair (defaultedAssocType , defaultType);
866+ return AbstractTypeWitness (assocType , defaultType, defaultedAssocType );
818867}
819868
820869std::pair<Type, TypeDecl *>
@@ -845,6 +894,29 @@ AssociatedTypeInference::computeDerivedTypeWitness(
845894 return result;
846895}
847896
897+ Optional<AbstractTypeWitness>
898+ AssociatedTypeInference::computeAbstractTypeWitness (
899+ AssociatedTypeDecl *assocType) {
900+ // We don't have a type witness for this associated type, so go
901+ // looking for more options.
902+ if (Type concreteType = computeFixedTypeWitness (assocType))
903+ return AbstractTypeWitness (assocType, concreteType);
904+
905+ // If we can form a default type, do so.
906+ if (const auto &typeWitness = computeDefaultTypeWitness (assocType))
907+ return typeWitness;
908+
909+ // If there is a generic parameter of the named type, use that.
910+ if (auto genericSig = dc->getGenericSignatureOfContext ()) {
911+ for (auto gp : genericSig.getInnermostGenericParams ()) {
912+ if (gp->getName () == assocType->getName ())
913+ return AbstractTypeWitness (assocType, gp);
914+ }
915+ }
916+
917+ return None;
918+ }
919+
848920void AssociatedTypeInference::collectAbstractTypeWitnesses (
849921 TypeWitnessSystem &system,
850922 ArrayRef<AssociatedTypeDecl *> unresolvedAssocTypes) const {
@@ -878,8 +950,9 @@ void AssociatedTypeInference::collectAbstractTypeWitnesses(
878950 }
879951
880952 // If we find a default type definition, feed it to the system.
881- if (const auto declAndType = computeDefaultTypeWitness (assocType)) {
882- system.addDefaultTypeWitness (declAndType->second , declAndType->first );
953+ if (const auto &typeWitness = computeDefaultTypeWitness (assocType)) {
954+ system.addDefaultTypeWitness (typeWitness->getType (),
955+ typeWitness->getDefaultedAssocType ());
883956 } else {
884957 // As a last resort, look for a generic parameter that matches the name
885958 // of the associated type.
@@ -1128,26 +1201,56 @@ AssociatedTypeDecl *AssociatedTypeInference::inferAbstractTypeWitnesses(
11281201 return nullptr ;
11291202 }
11301203
1131- TypeWitnessSystem system (unresolvedAssocTypes);
1132- collectAbstractTypeWitnesses (system, unresolvedAssocTypes);
1204+ // Attempt to compute abstract type witnesses for associated types that could
1205+ // not resolve otherwise.
1206+ llvm::SmallVector<AbstractTypeWitness, 2 > abstractTypeWitnesses;
11331207
1134- if (ctx.LangOpts .DumpTypeWitnessSystems ) {
1135- system. dump ( llvm::dbgs (), conformance );
1136- }
1208+ if (ctx.LangOpts .EnableExperimentalAssociatedTypeInference ) {
1209+ TypeWitnessSystem system (unresolvedAssocTypes );
1210+ collectAbstractTypeWitnesses (system, unresolvedAssocTypes);
11371211
1138- // If we couldn't resolve an associated type, bail out.
1139- for (auto *assocType : unresolvedAssocTypes) {
1140- if (!system.hasResolvedTypeWitness (assocType->getName ())) {
1141- return assocType;
1212+ if (ctx.LangOpts .DumpTypeWitnessSystems ) {
1213+ system.dump (llvm::dbgs (), conformance);
11421214 }
1143- }
11441215
1145- // Record the tentative type witnesses to make them available during
1146- // substitutions.
1147- for (auto *assocType : unresolvedAssocTypes) {
1148- typeWitnesses.insert (
1149- assocType,
1150- {system.getResolvedTypeWitness (assocType->getName ()), reqDepth});
1216+ // If we couldn't resolve an associated type, bail out.
1217+ for (auto *assocType : unresolvedAssocTypes) {
1218+ if (!system.hasResolvedTypeWitness (assocType->getName ())) {
1219+ return assocType;
1220+ }
1221+ }
1222+
1223+ // Record the tentative type witnesses to make them available during
1224+ // substitutions.
1225+ for (auto *assocType : unresolvedAssocTypes) {
1226+ auto resolvedTy = system.getResolvedTypeWitness (assocType->getName ());
1227+
1228+ typeWitnesses.insert (assocType, {resolvedTy, reqDepth});
1229+
1230+ if (auto *defaultedAssocType =
1231+ system.getDefaultedAssocType (assocType->getName ())) {
1232+ abstractTypeWitnesses.emplace_back (assocType, resolvedTy,
1233+ defaultedAssocType);
1234+ } else {
1235+ abstractTypeWitnesses.emplace_back (assocType, resolvedTy);
1236+ }
1237+ }
1238+ } else {
1239+ for (auto *const assocType : unresolvedAssocTypes) {
1240+ // Try to compute the type without the aid of a specific potential
1241+ // witness.
1242+ if (const auto &typeWitness = computeAbstractTypeWitness (assocType)) {
1243+ // Record the type witness immediately to make it available
1244+ // for substitutions into other tentative type witnesses.
1245+ typeWitnesses.insert (assocType, {typeWitness->getType (), reqDepth});
1246+
1247+ abstractTypeWitnesses.push_back (std::move (typeWitness.getValue ()));
1248+ continue ;
1249+ }
1250+
1251+ // The solution is incomplete.
1252+ return assocType;
1253+ }
11511254 }
11521255
11531256 // Check each abstract type witness against the generic requirements on the
@@ -1164,8 +1267,10 @@ AssociatedTypeDecl *AssociatedTypeInference::inferAbstractTypeWitnesses(
11641267 // associatedtype B: Sequence = Never
11651268 // }
11661269 const auto substOptions = getSubstOptionsWithCurrentTypeWitnesses ();
1167- for (auto *const assocType : unresolvedAssocTypes) {
1168- Type type = system.getResolvedTypeWitness (assocType->getName ());
1270+ for (const auto &witness : abstractTypeWitnesses) {
1271+ auto *const assocType = witness.getAssocType ();
1272+ Type type = witness.getType ();
1273+
11691274 // Replace type parameters with other known or tentative type witnesses.
11701275 if (type->hasTypeParameter ()) {
11711276 // FIXME: We should find a better way to detect and reason about these
@@ -1177,7 +1282,10 @@ AssociatedTypeDecl *AssociatedTypeInference::inferAbstractTypeWitnesses(
11771282 std::function<Type (Type)> substCurrentTypeWitnesses;
11781283 substCurrentTypeWitnesses = [&](Type ty) -> Type {
11791284 if (auto *gp = ty->getAs <GenericTypeParamType>()) {
1180- if (isa<ProtocolDecl>(gp->getDecl ()->getDeclContext ()->getAsDecl ())) {
1285+ // FIXME: 'computeFixedTypeWitness' uses 'getCanonicalTypeInContext',
1286+ // so if a generic parameter is canonical here, it's 'Self'.
1287+ if (gp->isCanonical () ||
1288+ isa<ProtocolDecl>(gp->getDecl ()->getDeclContext ()->getAsDecl ())) {
11811289 return adoptee;
11821290 }
11831291
@@ -1282,8 +1390,7 @@ AssociatedTypeDecl *AssociatedTypeInference::inferAbstractTypeWitnesses(
12821390 checkTypeWitness (type, assocType, conformance, substOptions)) {
12831391 // We failed to satisfy a requirement. If this is a default type
12841392 // witness failure and we haven't seen one already, write it down.
1285- auto *defaultedAssocType =
1286- system.getDefaultedAssocType (assocType->getName ());
1393+ auto *defaultedAssocType = witness.getDefaultedAssocType ();
12871394 if (defaultedAssocType && !failedDefaultedAssocType &&
12881395 !failed.isError ()) {
12891396 failedDefaultedAssocType = defaultedAssocType;
@@ -2187,7 +2294,7 @@ Type TypeWitnessSystem::getResolvedTypeWitness(Identifier name) const {
21872294 return Type ();
21882295}
21892296
2190- const AssociatedTypeDecl *
2297+ AssociatedTypeDecl *
21912298TypeWitnessSystem::getDefaultedAssocType (Identifier name) const {
21922299 assert (this ->TypeWitnesses .count (name));
21932300
@@ -2268,7 +2375,7 @@ void TypeWitnessSystem::addTypeWitness(Identifier name, Type type) {
22682375}
22692376
22702377void TypeWitnessSystem::addDefaultTypeWitness (
2271- Type type, const AssociatedTypeDecl *defaultedAssocType) {
2378+ Type type, AssociatedTypeDecl *defaultedAssocType) {
22722379 const auto name = defaultedAssocType->getName ();
22732380 assert (this ->TypeWitnesses .count (name));
22742381
0 commit comments