@@ -1222,85 +1222,79 @@ AssociatedTypeDecl *AssociatedTypeInference::inferAbstractTypeWitnesses(
1222
1222
return nullptr ;
1223
1223
}
1224
1224
1225
- // Examine the solution for errors and attempt to compute abstract type
1226
- // witnesses for associated types that are still lacking an entry.
1227
- llvm::SmallVector<AbstractTypeWitness, 2 > abstractTypeWitnesses;
1228
- for (auto *const assocType : unresolvedAssocTypes) {
1229
- // Try to compute the type without the aid of a specific potential witness.
1230
- if (const auto &typeWitness = computeAbstractTypeWitness (assocType)) {
1231
- // Record the type witness immediately to make it available
1232
- // for substitutions into other tentative type witnesses.
1233
- typeWitnesses.insert (assocType, {typeWitness->getType (), reqDepth});
1225
+ TypeWitnessSystem system (unresolvedAssocTypes);
1226
+ collectAbstractTypeWitnesses (system, unresolvedAssocTypes);
1234
1227
1235
- abstractTypeWitnesses.push_back (std::move (typeWitness.getValue ()));
1236
- continue ;
1228
+ // If we couldn't resolve an associated type, bail out.
1229
+ for (auto *assocType : unresolvedAssocTypes) {
1230
+ if (!system.hasResolvedTypeWitness (assocType->getName ())) {
1231
+ return assocType;
1237
1232
}
1233
+ }
1238
1234
1239
- // The solution is incomplete.
1240
- return assocType;
1235
+ // Record the tentative type witnesses to make them available during
1236
+ // substitutions.
1237
+ for (auto *assocType : unresolvedAssocTypes) {
1238
+ typeWitnesses.insert (
1239
+ assocType,
1240
+ {system.getResolvedTypeWitness (assocType->getName ()), reqDepth});
1241
1241
}
1242
1242
1243
- // Check each abstract type witness we computed against the generic
1244
- // requirements on the corresponding associated type.
1243
+ // Check each abstract type witness against the generic requirements on the
1244
+ // corresponding associated type.
1245
1245
const auto substOptions = getSubstOptionsWithCurrentTypeWitnesses ();
1246
- for (const auto &witness : abstractTypeWitnesses ) {
1247
- Type type = witness. getType ( );
1246
+ for (auto * const assocType : unresolvedAssocTypes ) {
1247
+ Type type = system. getResolvedTypeWitness (assocType-> getName () );
1248
1248
if (type->hasTypeParameter ()) {
1249
- if (witness.getKind () == AbstractTypeWitnessKind::GenericParam) {
1250
- type = type = dc->mapTypeIntoContext (type);
1251
- } else {
1252
- // Replace type parameters with other known or tentative type witnesses.
1253
- type = type.subst (
1254
- [&](SubstitutableType *type) {
1255
- if (type->isEqual (proto->getSelfInterfaceType ()))
1256
- return adoptee;
1249
+ // Replace type parameters with other known or tentative type witnesses.
1250
+ type = type.subst (
1251
+ [&](SubstitutableType *type) {
1252
+ if (type->isEqual (proto->getSelfInterfaceType ()))
1253
+ return adoptee;
1257
1254
1258
- return Type ();
1259
- },
1260
- LookUpConformanceInModule (dc->getParentModule ()), substOptions);
1255
+ return Type ();
1256
+ },
1257
+ LookUpConformanceInModule (dc->getParentModule ()), substOptions);
1258
+
1259
+ // If the substitution produced an error, give up.
1260
+ if (type->hasError ())
1261
+ return assocType;
1262
+
1263
+ // FIXME: We should find a better way to detect and reason about these
1264
+ // cyclic solutions.
1265
+ // If mapping into context yields an error, or we still have a type
1266
+ // parameter despite not having a generic environment, then a type
1267
+ // parameter was sent to a tentative type witness that itself is a type
1268
+ // parameter, and the solution is cyclic, e.g { A := B.A, B := A.B };
1269
+ // bail out in these cases.
1270
+ if (dc->isGenericContext ()) {
1271
+ type = dc->mapTypeIntoContext (type);
1261
1272
1262
- // If the substitution produced an error, we're done.
1263
1273
if (type->hasError ())
1264
- return witness.getAssocType ();
1265
-
1266
- // FIXME: If mapping into context yields an error, or we still have a
1267
- // type parameter despite not having a generic environment, then a type
1268
- // parameter was sent to a tentative type witness that itself is a type
1269
- // parameter, and the solution is cyclic, e.g. { A := B.A, B := A.B },
1270
- // or beyond the current algorithm, e.g.
1271
- // protocol P {
1272
- // associatedtype A = B
1273
- // associatedtype B = C
1274
- // associatedtype C = Int
1275
- // }
1276
- // struct Conformer: P {}
1277
- if (dc->getGenericEnvironmentOfContext ()) {
1278
- type = dc->mapTypeIntoContext (type);
1279
-
1280
- if (type->hasError ())
1281
- return witness.getAssocType ();
1282
- } else if (type->hasTypeParameter ()) {
1283
- return witness.getAssocType ();
1284
- }
1274
+ return assocType;
1275
+ } else if (type->hasTypeParameter ()) {
1276
+ return assocType;
1285
1277
}
1286
1278
}
1287
1279
1288
- if (const auto & failed = checkTypeWitness (type, witness. getAssocType (),
1289
- conformance, substOptions)) {
1280
+ if (const auto failed =
1281
+ checkTypeWitness (type, assocType, conformance, substOptions)) {
1290
1282
// We failed to satisfy a requirement. If this is a default type
1291
1283
// witness failure and we haven't seen one already, write it down.
1292
- if (witness.getKind () == AbstractTypeWitnessKind::Default &&
1293
- !failedDefaultedAssocType && !failed.isError ()) {
1294
- failedDefaultedAssocType = witness.getDefaultedAssocType ();
1284
+ auto *defaultedAssocType =
1285
+ system.getDefaultedAssocType (assocType->getName ());
1286
+ if (defaultedAssocType && !failedDefaultedAssocType &&
1287
+ !failed.isError ()) {
1288
+ failedDefaultedAssocType = defaultedAssocType;
1295
1289
failedDefaultedWitness = type;
1296
1290
failedDefaultedResult = std::move (failed);
1297
1291
}
1298
1292
1299
- return witness. getAssocType () ;
1293
+ return assocType ;
1300
1294
}
1301
1295
1302
- // Update the solution entry.
1303
- typeWitnesses.insert (witness. getAssocType () , {type, reqDepth});
1296
+ // Update the entry for this associated type .
1297
+ typeWitnesses.insert (assocType , {type, reqDepth});
1304
1298
}
1305
1299
1306
1300
return nullptr ;
0 commit comments