@@ -1342,6 +1342,25 @@ static SelfTypeKind getSelfTypeKind(DeclContext *dc,
1342
1342
}
1343
1343
}
1344
1344
1345
+ static void diagnoseGenericArgumentsOnSelf (TypeResolution resolution,
1346
+ ComponentIdentTypeRepr *comp,
1347
+ DeclContext *typeDC) {
1348
+ ASTContext &ctx = resolution.getASTContext ();
1349
+ auto &diags = ctx.Diags ;
1350
+
1351
+ auto *selfNominal = typeDC->getSelfNominalTypeDecl ();
1352
+ auto declaredType = selfNominal->getDeclaredType ();
1353
+
1354
+ diags.diagnose (comp->getNameLoc (), diag::cannot_specialize_self);
1355
+
1356
+ if (selfNominal->isGeneric () && !isa<ProtocolDecl>(selfNominal)) {
1357
+ diags.diagnose (comp->getNameLoc (), diag::specialize_explicit_type_instead,
1358
+ declaredType)
1359
+ .fixItReplace (comp->getNameLoc ().getSourceRange (),
1360
+ declaredType.getString ());
1361
+ }
1362
+ }
1363
+
1345
1364
// / Resolve the given identifier type representation as an unqualified type,
1346
1365
// / returning the type it references.
1347
1366
// /
@@ -1435,40 +1454,48 @@ static Type resolveTopLevelIdentTypeComponent(TypeResolution resolution,
1435
1454
return ErrorType::get (ctx);
1436
1455
}
1437
1456
1438
- // If we found nothing, complain and give ourselves a chance to recover.
1439
- if (current.isNull ()) {
1440
- // Dynamic 'Self' in the result type of a function body.
1441
- if (id.isSimpleName (ctx.Id_Self )) {
1442
- if (auto *typeDC = DC->getInnermostTypeContext ()) {
1443
- // FIXME: The passed-in TypeRepr should get 'typechecked' as well.
1444
- // The issue is though that ComponentIdentTypeRepr only accepts a ValueDecl
1445
- // while the 'Self' type is more than just a reference to a TypeDecl.
1446
- auto selfType = resolution.mapTypeIntoContext (
1447
- typeDC->getSelfInterfaceType ());
1448
-
1449
- // Check if we can reference Self here, and if so, what kind of Self it is.
1450
- switch (getSelfTypeKind (DC, options)) {
1451
- case SelfTypeKind::StaticSelf:
1452
- return selfType;
1453
- case SelfTypeKind::DynamicSelf:
1454
- return DynamicSelfType::get (selfType, ctx);
1455
- case SelfTypeKind::InvalidSelf:
1456
- break ;
1457
- }
1458
- }
1459
- }
1457
+ // If we found a type declaration with the given name, return it now.
1458
+ if (current) {
1459
+ comp->setValue (currentDecl, currentDC);
1460
+ return current;
1461
+ }
1460
1462
1461
- // If we're not allowed to complain or we couldn't fix the
1462
- // source, bail out.
1463
- if (options.contains (TypeResolutionFlags::SilenceErrors))
1464
- return ErrorType::get (ctx);
1463
+ // 'Self' inside of a nominal type refers to that type.
1464
+ if (id.isSimpleName (ctx.Id_Self )) {
1465
+ if (auto *typeDC = DC->getInnermostTypeContext ()) {
1466
+ // FIXME: The passed-in TypeRepr should get 'typechecked' as well.
1467
+ // The issue is though that ComponentIdentTypeRepr only accepts a ValueDecl
1468
+ // while the 'Self' type is more than just a reference to a TypeDecl.
1469
+ auto selfType = resolution.mapTypeIntoContext (
1470
+ typeDC->getSelfInterfaceType ());
1471
+
1472
+ // Check if we can reference 'Self' here, and if so, what kind of Self it is.
1473
+ auto selfTypeKind = getSelfTypeKind (DC, options);
1474
+
1475
+ // We don't allow generic arguments on 'Self'.
1476
+ if (selfTypeKind != SelfTypeKind::InvalidSelf &&
1477
+ isa<GenericIdentTypeRepr>(comp)) {
1478
+ diagnoseGenericArgumentsOnSelf (resolution, comp, typeDC);
1479
+ }
1465
1480
1466
- return diagnoseUnknownType (resolution, nullptr , SourceRange (), comp,
1467
- lookupOptions);
1481
+ switch (selfTypeKind) {
1482
+ case SelfTypeKind::StaticSelf:
1483
+ return selfType;
1484
+ case SelfTypeKind::DynamicSelf:
1485
+ return DynamicSelfType::get (selfType, ctx);
1486
+ case SelfTypeKind::InvalidSelf:
1487
+ break ;
1488
+ }
1489
+ }
1468
1490
}
1469
1491
1470
- comp->setValue (currentDecl, currentDC);
1471
- return current;
1492
+ // If we're not allowed to complain, bail out.
1493
+ if (options.contains (TypeResolutionFlags::SilenceErrors))
1494
+ return ErrorType::get (ctx);
1495
+
1496
+ // Complain and give ourselves a chance to recover.
1497
+ return diagnoseUnknownType (resolution, nullptr , SourceRange (), comp,
1498
+ lookupOptions);
1472
1499
}
1473
1500
1474
1501
static void diagnoseAmbiguousMemberType (Type baseTy, SourceRange baseRange,
0 commit comments