@@ -44,6 +44,25 @@ STATISTIC(NumDuplicateSolutionStates,
4444
4545using namespace swift ;
4646
47+ AbstractTypeWitness AbstractTypeWitness::forFixed (AssociatedTypeDecl *assocType,
48+ Type type) {
49+ return AbstractTypeWitness (AbstractTypeWitnessKind::Fixed, assocType, type,
50+ nullptr );
51+ }
52+
53+ AbstractTypeWitness
54+ AbstractTypeWitness::forDefault (AssociatedTypeDecl *assocType, Type type,
55+ AssociatedTypeDecl *defaultedAssocType) {
56+ return AbstractTypeWitness (AbstractTypeWitnessKind::Default, assocType, type,
57+ defaultedAssocType);
58+ }
59+
60+ AbstractTypeWitness
61+ AbstractTypeWitness::forGenericParam (AssociatedTypeDecl *assocType, Type type) {
62+ return AbstractTypeWitness (AbstractTypeWitnessKind::GenericParam, assocType,
63+ type, nullptr );
64+ }
65+
4766void InferredAssociatedTypesByWitness::dump () const {
4867 dump (llvm::errs (), 0 );
4968}
@@ -798,7 +817,56 @@ AssociatedTypeDecl *AssociatedTypeInference::findDefaultedAssociatedType(
798817 return results.size () == 1 ? results.front () : nullptr ;
799818}
800819
801- Optional<std::pair<AssociatedTypeDecl *, Type>>
820+ Type AssociatedTypeInference::computeFixedTypeWitness (
821+ AssociatedTypeDecl *assocType) {
822+ Type resultType;
823+
824+ // Look at all of the inherited protocols to determine whether they
825+ // require a fixed type for this associated type.
826+ for (auto conformedProto : adoptee->getAnyNominal ()->getAllProtocols ()) {
827+ if (conformedProto != assocType->getProtocol () &&
828+ !conformedProto->inheritsFrom (assocType->getProtocol ()))
829+ continue ;
830+
831+ auto sig = conformedProto->getGenericSignature ();
832+
833+ // FIXME: The RequirementMachine will assert on re-entrant construction.
834+ // We should find a more principled way of breaking this cycle.
835+ if (ctx.isRecursivelyConstructingRequirementMachine (sig.getCanonicalSignature ()) ||
836+ ctx.isRecursivelyConstructingRequirementMachine (conformedProto) ||
837+ conformedProto->isComputingRequirementSignature ())
838+ continue ;
839+
840+ auto selfTy = conformedProto->getSelfInterfaceType ();
841+ if (!sig->requiresProtocol (selfTy, assocType->getProtocol ()))
842+ continue ;
843+
844+ auto structuralTy = DependentMemberType::get (selfTy, assocType->getName ());
845+ const auto ty = sig.getCanonicalTypeInContext (structuralTy);
846+
847+ // A dependent member type with an identical base and name indicates that
848+ // the protocol does not same-type constrain it in any way; move on to
849+ // the next protocol.
850+ if (auto *const memberTy = ty->getAs <DependentMemberType>()) {
851+ if (memberTy->getBase ()->isEqual (selfTy) &&
852+ memberTy->getName () == assocType->getName ())
853+ continue ;
854+ }
855+
856+ if (!resultType) {
857+ resultType = ty;
858+ continue ;
859+ }
860+
861+ // FIXME: Bailing out on ambiguity.
862+ if (!resultType->isEqual (ty))
863+ return Type ();
864+ }
865+
866+ return resultType;
867+ }
868+
869+ Optional<AbstractTypeWitness>
802870AssociatedTypeInference::computeDefaultTypeWitness (
803871 AssociatedTypeDecl *assocType) const {
804872 // Go find a default definition.
@@ -814,7 +882,8 @@ AssociatedTypeInference::computeDefaultTypeWitness(
814882 if (defaultType->hasError ())
815883 return None;
816884
817- return std::make_pair (defaultedAssocType, defaultType);
885+ return AbstractTypeWitness::forDefault (assocType, defaultType,
886+ defaultedAssocType);
818887}
819888
820889std::pair<Type, TypeDecl *>
@@ -845,6 +914,29 @@ AssociatedTypeInference::computeDerivedTypeWitness(
845914 return result;
846915}
847916
917+ Optional<AbstractTypeWitness>
918+ AssociatedTypeInference::computeAbstractTypeWitness (
919+ AssociatedTypeDecl *assocType) {
920+ // We don't have a type witness for this associated type, so go
921+ // looking for more options.
922+ if (Type concreteType = computeFixedTypeWitness (assocType))
923+ return AbstractTypeWitness::forFixed (assocType, concreteType);
924+
925+ // If we can form a default type, do so.
926+ if (const auto &typeWitness = computeDefaultTypeWitness (assocType))
927+ return typeWitness;
928+
929+ // If there is a generic parameter of the named type, use that.
930+ if (auto genericSig = dc->getGenericSignatureOfContext ()) {
931+ for (auto gp : genericSig.getInnermostGenericParams ()) {
932+ if (gp->getName () == assocType->getName ())
933+ return AbstractTypeWitness::forGenericParam (assocType, gp);
934+ }
935+ }
936+
937+ return None;
938+ }
939+
848940void AssociatedTypeInference::collectAbstractTypeWitnesses (
849941 TypeWitnessSystem &system,
850942 ArrayRef<AssociatedTypeDecl *> unresolvedAssocTypes) const {
@@ -878,8 +970,9 @@ void AssociatedTypeInference::collectAbstractTypeWitnesses(
878970 }
879971
880972 // 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 );
973+ if (const auto &typeWitness = computeDefaultTypeWitness (assocType)) {
974+ system.addDefaultTypeWitness (typeWitness->getType (),
975+ typeWitness->getDefaultedAssocType ());
883976 } else {
884977 // As a last resort, look for a generic parameter that matches the name
885978 // of the associated type.
0 commit comments