@@ -43,6 +43,25 @@ STATISTIC(NumDuplicateSolutionStates,
4343
4444using namespace swift ;
4545
46+ AbstractTypeWitness AbstractTypeWitness::forFixed (AssociatedTypeDecl *assocType,
47+ Type type) {
48+ return AbstractTypeWitness (AbstractTypeWitnessKind::Fixed, assocType, type,
49+ nullptr );
50+ }
51+
52+ AbstractTypeWitness
53+ AbstractTypeWitness::forDefault (AssociatedTypeDecl *assocType, Type type,
54+ AssociatedTypeDecl *defaultedAssocType) {
55+ return AbstractTypeWitness (AbstractTypeWitnessKind::Default, assocType, type,
56+ defaultedAssocType);
57+ }
58+
59+ AbstractTypeWitness
60+ AbstractTypeWitness::forGenericParam (AssociatedTypeDecl *assocType, Type type) {
61+ return AbstractTypeWitness (AbstractTypeWitnessKind::GenericParam, assocType,
62+ type, nullptr );
63+ }
64+
4665void InferredAssociatedTypesByWitness::dump () const {
4766 dump (llvm::errs (), 0 );
4867}
@@ -811,65 +830,24 @@ Type AssociatedTypeInference::computeFixedTypeWitness(
811830 return resultType;
812831}
813832
814- Type AssociatedTypeInference::computeDefaultTypeWitness (
815- AssociatedTypeDecl *assocType) {
833+ Optional<AbstractTypeWitness>
834+ AssociatedTypeInference::computeDefaultTypeWitness (
835+ AssociatedTypeDecl *assocType) {
816836 // Go find a default definition.
817- auto defaultedAssocType = findDefaultedAssociatedType (assocType);
818- if (!defaultedAssocType) return Type ();
819-
820- // If we don't have a default definition, we're done.
821- auto selfType = proto->getSelfInterfaceType ();
822-
823- // Create a set of type substitutions for all known associated type.
824- // FIXME: Base this on dependent types rather than archetypes?
825- TypeSubstitutionMap substitutions;
826- substitutions[proto->mapTypeIntoContext (selfType)
827- ->castTo <ArchetypeType>()] = dc->mapTypeIntoContext (adoptee);
828- for (auto assocType : proto->getAssociatedTypeMembers ()) {
829- auto archetype = proto->mapTypeIntoContext (
830- assocType->getDeclaredInterfaceType ())
831- ->getAs <ArchetypeType>();
832- if (!archetype)
833- continue ;
834- if (conformance->hasTypeWitness (assocType)) {
835- substitutions[archetype] =
836- dc->mapTypeIntoContext (conformance->getTypeWitness (assocType));
837- } else {
838- auto known = typeWitnesses.begin (assocType);
839- if (known != typeWitnesses.end ())
840- substitutions[archetype] = known->first ;
841- else
842- substitutions[archetype] = ErrorType::get (archetype);
843- }
844- }
845-
846- Type defaultType = defaultedAssocType->getDefaultDefinitionType ();
837+ auto *const defaultedAssocType = findDefaultedAssociatedType (assocType);
838+ if (!defaultedAssocType)
839+ return None;
847840
841+ const Type defaultType = defaultedAssocType->getDefaultDefinitionType ();
848842 // FIXME: Circularity
849843 if (!defaultType)
850- return Type ();
851-
852- // Map it into our protocol's context.
853- defaultType = proto->mapTypeIntoContext (defaultType);
854- defaultType = defaultType.subst (
855- QueryTypeSubstitutionMap{substitutions},
856- LookUpConformanceInModule (dc->getParentModule ()));
844+ return None;
857845
858846 if (defaultType->hasError ())
859- return Type ();
860-
861- if (auto failed = checkTypeWitness (defaultType, assocType, conformance)) {
862- // Record the failure, if we haven't seen one already.
863- if (!failedDefaultedAssocType && !failed.isError ()) {
864- failedDefaultedAssocType = defaultedAssocType;
865- failedDefaultedWitness = defaultType;
866- failedDefaultedResult = failed;
867- }
868-
869- return Type ();
870- }
847+ return None;
871848
872- return defaultType;
849+ return AbstractTypeWitness::forDefault (assocType, defaultType,
850+ defaultedAssocType);
873851}
874852
875853std::pair<Type, TypeDecl *>
@@ -900,27 +878,27 @@ AssociatedTypeInference::computeDerivedTypeWitness(
900878 return result;
901879}
902880
903- Type
881+ Optional<AbstractTypeWitness>
904882AssociatedTypeInference::computeAbstractTypeWitness (
905- AssociatedTypeDecl *assocType) {
883+ AssociatedTypeDecl *assocType) {
906884 // We don't have a type witness for this associated type, so go
907885 // looking for more options.
908886 if (Type concreteType = computeFixedTypeWitness (assocType))
909- return concreteType;
887+ return AbstractTypeWitness::forFixed (assocType, concreteType) ;
910888
911889 // If we can form a default type, do so.
912- if (Type defaultType = computeDefaultTypeWitness (assocType))
913- return defaultType ;
890+ if (auto typeWitness = computeDefaultTypeWitness (assocType))
891+ return typeWitness ;
914892
915893 // If there is a generic parameter of the named type, use that.
916894 if (auto genericSig = dc->getGenericSignatureOfContext ()) {
917895 for (auto gp : genericSig->getInnermostGenericParams ()) {
918896 if (gp->getName () == assocType->getName ())
919- return dc-> mapTypeIntoContext ( gp);
897+ return AbstractTypeWitness::forGenericParam (assocType, gp);
920898 }
921899 }
922900
923- return Type () ;
901+ return None ;
924902}
925903
926904Type AssociatedTypeInference::substCurrentTypeWitnesses (Type type) {
@@ -1064,7 +1042,8 @@ AssociatedTypeInference::getSubstOptionsWithCurrentTypeWitnesses() {
10641042 if (auto *aliasTy = dyn_cast<TypeAliasType>(type.getPointer ()))
10651043 type = aliasTy->getSinglyDesugaredType ();
10661044
1067- return type->mapTypeOutOfContext ().getPointer ();
1045+ return type->hasArchetype () ? type->mapTypeOutOfContext ().getPointer ()
1046+ : type.getPointer ();
10681047 };
10691048 return options;
10701049}
@@ -1149,6 +1128,81 @@ bool AssociatedTypeInference::checkConstrainedExtension(ExtensionDecl *ext) {
11491128 llvm_unreachable (" unhandled result" );
11501129}
11511130
1131+ AssociatedTypeDecl *AssociatedTypeInference::completeSolution (
1132+ ArrayRef<AssociatedTypeDecl *> unresolvedAssocTypes, unsigned reqDepth) {
1133+ // Examine the solution for errors and attempt to compute abstract type
1134+ // witnesses for associated types that are still lacking an entry.
1135+ llvm::SmallVector<AbstractTypeWitness, 2 > abstractTypeWitnesses;
1136+ for (auto *const assocType : unresolvedAssocTypes) {
1137+ const auto typeWitness = typeWitnesses.begin (assocType);
1138+ if (typeWitness != typeWitnesses.end ()) {
1139+ // The solution contains an error.
1140+ if (typeWitness->first ->hasError ()) {
1141+ return assocType;
1142+ }
1143+
1144+ continue ;
1145+ }
1146+
1147+ // Try to compute the type without the aid of a specific potential witness.
1148+ if (const auto &typeWitness = computeAbstractTypeWitness (assocType)) {
1149+ // Record the type witness immediately to make it available
1150+ // for substitutions into other tentative type witnesses.
1151+ typeWitnesses.insert (assocType, {typeWitness->getType (), reqDepth});
1152+
1153+ abstractTypeWitnesses.push_back (std::move (typeWitness.getValue ()));
1154+ continue ;
1155+ }
1156+
1157+ // The solution is incomplete.
1158+ return assocType;
1159+ }
1160+
1161+ // Check each abstract type witness we computed against the generic
1162+ // requirements on the corresponding associated type.
1163+ for (const auto &witness : abstractTypeWitnesses) {
1164+ Type type = witness.getType ();
1165+ if (type->hasTypeParameter ()) {
1166+ if (witness.getKind () != AbstractTypeWitnessKind::GenericParam) {
1167+ // Replace type parameters with other known or tentative type witnesses.
1168+ type = type.subst (
1169+ [&](SubstitutableType *type) {
1170+ if (type->isEqual (proto->getSelfInterfaceType ()))
1171+ return adoptee;
1172+
1173+ return Type ();
1174+ },
1175+ LookUpConformanceInModule (dc->getParentModule ()),
1176+ getSubstOptionsWithCurrentTypeWitnesses ());
1177+
1178+ // If the substitution produced an error, we're done.
1179+ if (type->hasError ())
1180+ return witness.getAssocType ();
1181+ }
1182+ type = dc->mapTypeIntoContext (type);
1183+ }
1184+
1185+ if (const auto &failed =
1186+ checkTypeWitness (type, witness.getAssocType (), conformance)) {
1187+ // We failed to satisfy a requirement. If this is a default type
1188+ // witness failure and we haven't seen one already, write it down.
1189+ if (witness.getKind () == AbstractTypeWitnessKind::Default &&
1190+ !failedDefaultedAssocType && !failed.isError ()) {
1191+ failedDefaultedAssocType = witness.getDefaultedAssocType ();
1192+ failedDefaultedWitness = type;
1193+ failedDefaultedResult = std::move (failed);
1194+ }
1195+
1196+ return witness.getAssocType ();
1197+ }
1198+
1199+ // Update the solution entry.
1200+ typeWitnesses.insert (witness.getAssocType (), {type, reqDepth});
1201+ }
1202+
1203+ return nullptr ;
1204+ }
1205+
11521206void AssociatedTypeInference::findSolutions (
11531207 ArrayRef<AssociatedTypeDecl *> unresolvedAssocTypes,
11541208 SmallVectorImpl<InferredTypeWitnessesSolution> &solutions) {
@@ -1173,39 +1227,14 @@ void AssociatedTypeInference::findSolutionsRec(
11731227 // Introduce a hash table scope; we may add type witnesses here.
11741228 TypeWitnessesScope typeWitnessesScope (typeWitnesses);
11751229
1176- // Check for completeness of the solution
1177- for (auto assocType : unresolvedAssocTypes) {
1178- // Local function to record a missing associated type.
1179- auto recordMissing = [&] {
1180- if (!missingTypeWitness)
1181- missingTypeWitness = assocType;
1182- };
1183-
1184- auto typeWitness = typeWitnesses.begin (assocType);
1185- if (typeWitness != typeWitnesses.end ()) {
1186- // The solution contains an error.
1187- if (typeWitness->first ->hasError ()) {
1188- recordMissing ();
1189- return ;
1190- }
1191-
1192- continue ;
1193- }
1194-
1195- // Try to compute the type without the aid of a specific potential
1196- // witness.
1197- if (Type type = computeAbstractTypeWitness (assocType)) {
1198- if (type->hasError ()) {
1199- recordMissing ();
1200- return ;
1201- }
1202-
1203- typeWitnesses.insert (assocType, {type, reqDepth});
1204- continue ;
1205- }
1230+ // Validate and complete the solution.
1231+ if (auto *const assocType =
1232+ completeSolution (unresolvedAssocTypes, reqDepth)) {
1233+ // The solution is decisively incomplete; record the associated type
1234+ // we failed on and bail out.
1235+ if (!missingTypeWitness)
1236+ missingTypeWitness = assocType;
12061237
1207- // The solution is incomplete.
1208- recordMissing ();
12091238 return ;
12101239 }
12111240
0 commit comments