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