@@ -1342,6 +1342,25 @@ static SelfTypeKind getSelfTypeKind(DeclContext *dc,
13421342 }
13431343}
13441344
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+
13451364// / Resolve the given identifier type representation as an unqualified type,
13461365// / returning the type it references.
13471366// /
@@ -1435,40 +1454,48 @@ static Type resolveTopLevelIdentTypeComponent(TypeResolution resolution,
14351454 return ErrorType::get (ctx);
14361455 }
14371456
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+ }
14601462
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+ }
14651480
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+ }
14681490 }
14691491
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);
14721499}
14731500
14741501static void diagnoseAmbiguousMemberType (Type baseTy, SourceRange baseRange,
0 commit comments