@@ -43,6 +43,25 @@ STATISTIC(NumDuplicateSolutionStates,
43
43
44
44
using namespace swift ;
45
45
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
+
46
65
void InferredAssociatedTypesByWitness::dump () const {
47
66
dump (llvm::errs (), 0 );
48
67
}
@@ -811,65 +830,24 @@ Type AssociatedTypeInference::computeFixedTypeWitness(
811
830
return resultType;
812
831
}
813
832
814
- Type AssociatedTypeInference::computeDefaultTypeWitness (
815
- AssociatedTypeDecl *assocType) {
833
+ Optional<AbstractTypeWitness>
834
+ AssociatedTypeInference::computeDefaultTypeWitness (
835
+ AssociatedTypeDecl *assocType) {
816
836
// 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;
847
840
841
+ const Type defaultType = defaultedAssocType->getDefaultDefinitionType ();
848
842
// FIXME: Circularity
849
843
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;
857
845
858
846
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;
871
848
872
- return defaultType;
849
+ return AbstractTypeWitness::forDefault (assocType, defaultType,
850
+ defaultedAssocType);
873
851
}
874
852
875
853
std::pair<Type, TypeDecl *>
@@ -900,27 +878,27 @@ AssociatedTypeInference::computeDerivedTypeWitness(
900
878
return result;
901
879
}
902
880
903
- Type
881
+ Optional<AbstractTypeWitness>
904
882
AssociatedTypeInference::computeAbstractTypeWitness (
905
- AssociatedTypeDecl *assocType) {
883
+ AssociatedTypeDecl *assocType) {
906
884
// We don't have a type witness for this associated type, so go
907
885
// looking for more options.
908
886
if (Type concreteType = computeFixedTypeWitness (assocType))
909
- return concreteType;
887
+ return AbstractTypeWitness::forFixed (assocType, concreteType) ;
910
888
911
889
// 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 ;
914
892
915
893
// If there is a generic parameter of the named type, use that.
916
894
if (auto genericSig = dc->getGenericSignatureOfContext ()) {
917
895
for (auto gp : genericSig->getInnermostGenericParams ()) {
918
896
if (gp->getName () == assocType->getName ())
919
- return dc-> mapTypeIntoContext ( gp);
897
+ return AbstractTypeWitness::forGenericParam (assocType, gp);
920
898
}
921
899
}
922
900
923
- return Type () ;
901
+ return None ;
924
902
}
925
903
926
904
Type AssociatedTypeInference::substCurrentTypeWitnesses (Type type) {
@@ -1064,7 +1042,8 @@ AssociatedTypeInference::getSubstOptionsWithCurrentTypeWitnesses() {
1064
1042
if (auto *aliasTy = dyn_cast<TypeAliasType>(type.getPointer ()))
1065
1043
type = aliasTy->getSinglyDesugaredType ();
1066
1044
1067
- return type->mapTypeOutOfContext ().getPointer ();
1045
+ return type->hasArchetype () ? type->mapTypeOutOfContext ().getPointer ()
1046
+ : type.getPointer ();
1068
1047
};
1069
1048
return options;
1070
1049
}
@@ -1149,6 +1128,81 @@ bool AssociatedTypeInference::checkConstrainedExtension(ExtensionDecl *ext) {
1149
1128
llvm_unreachable (" unhandled result" );
1150
1129
}
1151
1130
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
+
1152
1206
void AssociatedTypeInference::findSolutions (
1153
1207
ArrayRef<AssociatedTypeDecl *> unresolvedAssocTypes,
1154
1208
SmallVectorImpl<InferredTypeWitnessesSolution> &solutions) {
@@ -1173,39 +1227,14 @@ void AssociatedTypeInference::findSolutionsRec(
1173
1227
// Introduce a hash table scope; we may add type witnesses here.
1174
1228
TypeWitnessesScope typeWitnessesScope (typeWitnesses);
1175
1229
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;
1206
1237
1207
- // The solution is incomplete.
1208
- recordMissing ();
1209
1238
return ;
1210
1239
}
1211
1240
0 commit comments