@@ -1279,22 +1279,20 @@ static Type resolveNestedIdentTypeComponent(
1279
1279
// associated type but the type itself was erroneous. We'll produce a
1280
1280
// diagnostic here if the diagnostic for the bad type witness would show up in
1281
1281
// a different context.
1282
- auto maybeDiagnoseBadConformanceRef = [&](AssociatedTypeDecl *assocType,
1283
- ProtocolConformance *conformance) {
1282
+ auto maybeDiagnoseBadConformanceRef = [&](AssociatedTypeDecl *assocType) {
1284
1283
// If we aren't emitting any diagnostics, we're done.
1285
1284
if (!diagnoseErrors)
1286
1285
return ;
1287
1286
1288
1287
// If we weren't given a conformance, go look it up.
1289
- if (!conformance) {
1290
- if (auto conformanceRef =
1291
- TC.conformsToProtocol (
1292
- parentTy, assocType->getProtocol (), DC,
1293
- (ConformanceCheckFlags::InExpression|
1294
- ConformanceCheckFlags::SuppressDependencyTracking))) {
1295
- if (conformanceRef->isConcrete ())
1296
- conformance = conformanceRef->getConcrete ();
1297
- }
1288
+ ProtocolConformance *conformance = nullptr ;
1289
+ if (auto conformanceRef =
1290
+ TC.conformsToProtocol (
1291
+ parentTy, assocType->getProtocol (), DC,
1292
+ (ConformanceCheckFlags::InExpression|
1293
+ ConformanceCheckFlags::SuppressDependencyTracking))) {
1294
+ if (conformanceRef->isConcrete ())
1295
+ conformance = conformanceRef->getConcrete ();
1298
1296
}
1299
1297
1300
1298
// If there is a conformance and it comes from the same source file as type
@@ -1313,38 +1311,58 @@ static Type resolveNestedIdentTypeComponent(
1313
1311
assocType->getFullName (), parentTy);
1314
1312
};
1315
1313
1316
- // Short-circuiting.
1317
- if (comp->isInvalid ()) return ErrorType::get (TC.Context );
1314
+ auto maybeDiagnoseBadMemberType = [&](TypeDecl *member, Type memberType) {
1315
+ // Diagnose invalid cases.
1316
+ if (TC.isUnsupportedMemberTypeAccess (parentTy, member)) {
1317
+ if (diagnoseErrors) {
1318
+ if (parentTy->is <UnboundGenericType>())
1319
+ diagnoseUnboundGenericType (TC, parentTy, parentRange.End );
1320
+ else if (parentTy->isExistentialType () &&
1321
+ isa<AssociatedTypeDecl>(member)) {
1322
+ TC.diagnose (comp->getIdLoc (), diag::assoc_type_outside_of_protocol,
1323
+ comp->getIdentifier ());
1324
+ } else if (parentTy->isExistentialType () &&
1325
+ isa<TypeAliasDecl>(member)) {
1326
+ TC.diagnose (comp->getIdLoc (), diag::typealias_outside_of_protocol,
1327
+ comp->getIdentifier ());
1328
+ }
1329
+ }
1318
1330
1319
- // If the parent is a type parameter, the member is a dependent member,
1320
- // and we skip much of the work below.
1321
- if (parentTy->isTypeParameter ()) {
1322
- auto memberType = resolver->resolveDependentMemberType (parentTy, DC,
1323
- parentRange, comp);
1324
- assert (memberType && " Received null dependent member type" );
1325
- return memberType;
1326
- }
1331
+ return ErrorType::get (TC.Context );
1332
+ }
1327
1333
1328
- // Phase 2: If a declaration has already been bound, use it.
1329
- if (auto *typeDecl = comp->getBoundDecl ()) {
1330
- // Otherwise, simply substitute the parent type into the member.
1331
- auto memberType = TC.substMemberTypeWithBase (DC->getParentModule (),
1332
- typeDecl, parentTy);
1334
+ // Only the last component of the underlying type of a type alias may
1335
+ // be an unbound generic.
1336
+ if (options & TR_TypeAliasUnderlyingType) {
1337
+ if (parentTy->is <UnboundGenericType>()) {
1338
+ if (diagnoseErrors)
1339
+ diagnoseUnboundGenericType (TC, parentTy, parentRange.End );
1333
1340
1334
- // Diagnose the bad reference if we need to.
1335
- if (typeDecl && isa<AssociatedTypeDecl>(typeDecl) && memberType-> hasError ())
1336
- maybeDiagnoseBadConformanceRef (cast<AssociatedTypeDecl>(typeDecl), nullptr );
1341
+ return ErrorType::get (TC. Context );
1342
+ }
1343
+ }
1337
1344
1338
- // Propagate failure.
1345
+ // If we found a reference to an associated type or other member type that
1346
+ // was marked invalid, just return ErrorType to silence downstream errors.
1347
+ if (member->isInvalid ())
1348
+ return ErrorType::get (TC.Context );
1349
+
1350
+ // Diagnose a bad conformance reference if we need to.
1351
+ if (isa<AssociatedTypeDecl>(member) &&
1352
+ memberType &&
1353
+ memberType->hasError ())
1354
+ maybeDiagnoseBadConformanceRef (cast<AssociatedTypeDecl>(member));
1355
+
1356
+ // At this point, we need to have resolved the type of the member.
1339
1357
if (!memberType || memberType->hasError ()) return memberType;
1340
1358
1341
1359
// If there are generic arguments, apply them now.
1342
1360
if (auto genComp = dyn_cast<GenericIdentTypeRepr>(comp)) {
1343
1361
return TC.applyGenericArguments (
1344
- memberType, typeDecl , comp->getIdLoc (), DC, genComp,
1362
+ memberType, member , comp->getIdLoc (), DC, genComp,
1345
1363
options, resolver, unsatisfiedDependency);
1346
1364
}
1347
-
1365
+
1348
1366
if (memberType->is <UnboundGenericType>() &&
1349
1367
!options.contains (TR_AllowUnboundGenerics) &&
1350
1368
!options.contains (TR_TypeAliasUnderlyingType) &&
@@ -1353,8 +1371,26 @@ static Type resolveNestedIdentTypeComponent(
1353
1371
return ErrorType::get (TC.Context );
1354
1372
}
1355
1373
1356
- // We're done.
1357
1374
return memberType;
1375
+ };
1376
+
1377
+ // Short-circuiting.
1378
+ if (comp->isInvalid ()) return ErrorType::get (TC.Context );
1379
+
1380
+ // If the parent is a type parameter, the member is a dependent member,
1381
+ // and we skip much of the work below.
1382
+ if (parentTy->isTypeParameter ()) {
1383
+ auto memberType = resolver->resolveDependentMemberType (parentTy, DC,
1384
+ parentRange, comp);
1385
+ assert (memberType && " Received null dependent member type" );
1386
+ return memberType;
1387
+ }
1388
+
1389
+ // Phase 2: If a declaration has already been bound, use it.
1390
+ if (auto *typeDecl = comp->getBoundDecl ()) {
1391
+ auto memberType = TC.substMemberTypeWithBase (DC->getParentModule (),
1392
+ typeDecl, parentTy);
1393
+ return maybeDiagnoseBadMemberType (typeDecl, memberType);
1358
1394
}
1359
1395
1360
1396
// Phase 1: Find and bind the component decl.
@@ -1412,77 +1448,22 @@ static Type resolveNestedIdentTypeComponent(
1412
1448
if (!memberTypes) {
1413
1449
// If we're not allowed to complain or we couldn't fix the
1414
1450
// source, bail out.
1415
- if (!diagnoseErrors) {
1451
+ if (!diagnoseErrors)
1416
1452
return ErrorType::get (TC.Context );
1417
- }
1418
1453
1419
- Type ty = diagnoseUnknownType (TC, DC, parentTy, parentRange, comp, options,
1420
- lookupOptions, resolver,
1421
- unsatisfiedDependency);
1422
- if (!ty || ty->hasError ()) {
1423
- return ErrorType::get (TC.Context );
1424
- }
1425
-
1426
- memberType = ty;
1454
+ memberType = diagnoseUnknownType (TC, DC, parentTy, parentRange, comp,
1455
+ options, lookupOptions, resolver,
1456
+ unsatisfiedDependency);
1427
1457
member = comp->getBoundDecl ();
1458
+ if (!member)
1459
+ return ErrorType::get (TC.Context );
1428
1460
} else {
1429
1461
memberType = memberTypes.back ().second ;
1430
1462
member = memberTypes.back ().first ;
1463
+ comp->setValue (member);
1431
1464
}
1432
1465
1433
- // Diagnose invalid cases.
1434
- if (TC.isUnsupportedMemberTypeAccess (parentTy, member)) {
1435
- if (diagnoseErrors) {
1436
- if (parentTy->is <UnboundGenericType>())
1437
- diagnoseUnboundGenericType (TC, parentTy, parentRange.End );
1438
- else if (parentTy->isExistentialType () &&
1439
- isa<AssociatedTypeDecl>(member)) {
1440
- TC.diagnose (comp->getIdLoc (), diag::assoc_type_outside_of_protocol,
1441
- comp->getIdentifier ());
1442
- } else if (parentTy->isExistentialType () &&
1443
- isa<TypeAliasDecl>(member)) {
1444
- TC.diagnose (comp->getIdLoc (), diag::typealias_outside_of_protocol,
1445
- comp->getIdentifier ());
1446
- }
1447
- }
1448
-
1449
- return ErrorType::get (TC.Context );
1450
- }
1451
-
1452
- if (options & TR_TypeAliasUnderlyingType) {
1453
- if (parentTy->is <UnboundGenericType>()) {
1454
- if (diagnoseErrors)
1455
- diagnoseUnboundGenericType (TC, parentTy, parentRange.End );
1456
-
1457
- return ErrorType::get (TC.Context );
1458
- }
1459
- }
1460
-
1461
- // If there are generic arguments, apply them now.
1462
- if (auto genComp = dyn_cast<GenericIdentTypeRepr>(comp)) {
1463
- memberType = TC.applyGenericArguments (
1464
- memberType, member, comp->getIdLoc (), DC, genComp,
1465
- options, resolver, unsatisfiedDependency);
1466
- } else if (memberType->is <UnboundGenericType>() &&
1467
- !options.contains (TR_AllowUnboundGenerics) &&
1468
- !options.contains (TR_TypeAliasUnderlyingType) &&
1469
- !options.contains (TR_ResolveStructure)) {
1470
- diagnoseUnboundGenericType (TC, memberType, comp->getLoc ());
1471
- memberType = ErrorType::get (TC.Context );
1472
- }
1473
-
1474
- // If we found a reference to an associated type or other member type that
1475
- // was marked invalid, just return ErrorType to silence downstream errors.
1476
- if (member && member->isInvalid ())
1477
- memberType = ErrorType::get (TC.Context );
1478
-
1479
- // Diagnose the bad reference if we need to.
1480
- if (member && isa<AssociatedTypeDecl>(member) && memberType->hasError ())
1481
- maybeDiagnoseBadConformanceRef (cast<AssociatedTypeDecl>(member), nullptr );
1482
-
1483
- if (member)
1484
- comp->setValue (member);
1485
- return memberType;
1466
+ return maybeDiagnoseBadMemberType (member, memberType);
1486
1467
}
1487
1468
1488
1469
static Type resolveIdentTypeComponent (
0 commit comments