@@ -1201,26 +1201,56 @@ AssociatedTypeDecl *AssociatedTypeInference::inferAbstractTypeWitnesses(
1201
1201
return nullptr ;
1202
1202
}
1203
1203
1204
- TypeWitnessSystem system (unresolvedAssocTypes);
1205
- 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;
1206
1207
1207
- if (ctx.LangOpts .DumpTypeWitnessSystems ) {
1208
- system. dump ( llvm::dbgs (), conformance );
1209
- }
1208
+ if (ctx.LangOpts .EnableExperimentalAssociatedTypeInference ) {
1209
+ TypeWitnessSystem system (unresolvedAssocTypes );
1210
+ collectAbstractTypeWitnesses (system, unresolvedAssocTypes);
1210
1211
1211
- // If we couldn't resolve an associated type, bail out.
1212
- for (auto *assocType : unresolvedAssocTypes) {
1213
- if (!system.hasResolvedTypeWitness (assocType->getName ())) {
1214
- return assocType;
1212
+ if (ctx.LangOpts .DumpTypeWitnessSystems ) {
1213
+ system.dump (llvm::dbgs (), conformance);
1215
1214
}
1216
- }
1217
1215
1218
- // Record the tentative type witnesses to make them available during
1219
- // substitutions.
1220
- for (auto *assocType : unresolvedAssocTypes) {
1221
- typeWitnesses.insert (
1222
- assocType,
1223
- {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
+ }
1224
1254
}
1225
1255
1226
1256
// Check each abstract type witness against the generic requirements on the
@@ -1237,8 +1267,10 @@ AssociatedTypeDecl *AssociatedTypeInference::inferAbstractTypeWitnesses(
1237
1267
// associatedtype B: Sequence = Never
1238
1268
// }
1239
1269
const auto substOptions = getSubstOptionsWithCurrentTypeWitnesses ();
1240
- for (auto *const assocType : unresolvedAssocTypes) {
1241
- Type type = system.getResolvedTypeWitness (assocType->getName ());
1270
+ for (const auto &witness : abstractTypeWitnesses) {
1271
+ auto *const assocType = witness.getAssocType ();
1272
+ Type type = witness.getType ();
1273
+
1242
1274
// Replace type parameters with other known or tentative type witnesses.
1243
1275
if (type->hasTypeParameter ()) {
1244
1276
// FIXME: We should find a better way to detect and reason about these
@@ -1250,7 +1282,10 @@ AssociatedTypeDecl *AssociatedTypeInference::inferAbstractTypeWitnesses(
1250
1282
std::function<Type (Type)> substCurrentTypeWitnesses;
1251
1283
substCurrentTypeWitnesses = [&](Type ty) -> Type {
1252
1284
if (auto *gp = ty->getAs <GenericTypeParamType>()) {
1253
- 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 ())) {
1254
1289
return adoptee;
1255
1290
}
1256
1291
@@ -1355,8 +1390,7 @@ AssociatedTypeDecl *AssociatedTypeInference::inferAbstractTypeWitnesses(
1355
1390
checkTypeWitness (type, assocType, conformance, substOptions)) {
1356
1391
// We failed to satisfy a requirement. If this is a default type
1357
1392
// witness failure and we haven't seen one already, write it down.
1358
- auto *defaultedAssocType =
1359
- system.getDefaultedAssocType (assocType->getName ());
1393
+ auto *defaultedAssocType = witness.getDefaultedAssocType ();
1360
1394
if (defaultedAssocType && !failedDefaultedAssocType &&
1361
1395
!failed.isError ()) {
1362
1396
failedDefaultedAssocType = defaultedAssocType;
@@ -2260,7 +2294,7 @@ Type TypeWitnessSystem::getResolvedTypeWitness(Identifier name) const {
2260
2294
return Type ();
2261
2295
}
2262
2296
2263
- const AssociatedTypeDecl *
2297
+ AssociatedTypeDecl *
2264
2298
TypeWitnessSystem::getDefaultedAssocType (Identifier name) const {
2265
2299
assert (this ->TypeWitnesses .count (name));
2266
2300
@@ -2341,7 +2375,7 @@ void TypeWitnessSystem::addTypeWitness(Identifier name, Type type) {
2341
2375
}
2342
2376
2343
2377
void TypeWitnessSystem::addDefaultTypeWitness (
2344
- Type type, const AssociatedTypeDecl *defaultedAssocType) {
2378
+ Type type, AssociatedTypeDecl *defaultedAssocType) {
2345
2379
const auto name = defaultedAssocType->getName ();
2346
2380
assert (this ->TypeWitnesses .count (name));
2347
2381
0 commit comments