@@ -4148,29 +4148,29 @@ class ExistentialTypeVisitor
41484148 if (proto->existentialRequiresAny ()) {
41494149 Ctx.Diags .diagnose (comp->getNameLoc (),
41504150 diag::existential_requires_any,
4151- proto->getName ())
4151+ proto->getDeclaredInterfaceType (),
4152+ /* isAlias=*/ false )
41524153 .limitBehavior (DiagnosticBehavior::Warning);
41534154 }
41544155 } else if (auto *alias = dyn_cast_or_null<TypeAliasDecl>(comp->getBoundDecl ())) {
41554156 auto type = Type (alias->getDeclaredInterfaceType ()->getDesugaredType ());
4156- type. findIf ([&](Type type) -> bool {
4157- if (T-> isInvalid ())
4158- return false ;
4159- if (type->isExistentialType ()) {
4160- auto layout = type->getExistentialLayout ();
4161- for (auto *proto : layout.getProtocols ()) {
4162- auto *protoDecl = proto->getDecl ();
4163- if (!protoDecl->existentialRequiresAny ())
4164- continue ;
4157+ // If this is a type alias to a constraint type, the type
4158+ // alias name must be prefixed with 'any' to be used as an
4159+ // existential type.
4160+ if (type->isConstraintType ()) {
4161+ auto layout = type->getExistentialLayout ();
4162+ for (auto *proto : layout.getProtocols ()) {
4163+ auto *protoDecl = proto->getDecl ();
4164+ if (!protoDecl->existentialRequiresAny ())
4165+ continue ;
41654166
4166- Ctx.Diags .diagnose (comp->getNameLoc (),
4167- diag::existential_requires_any,
4168- protoDecl-> getName ())
4169- . limitBehavior (DiagnosticBehavior::Warning);
4170- }
4167+ Ctx.Diags .diagnose (comp->getNameLoc (),
4168+ diag::existential_requires_any,
4169+ alias-> getDeclaredInterfaceType (),
4170+ /* isAlias= */ true )
4171+ . limitBehavior (DiagnosticBehavior::Warning);
41714172 }
4172- return false ;
4173- });
4173+ }
41744174 }
41754175 }
41764176
@@ -4198,6 +4198,9 @@ void TypeChecker::checkExistentialTypes(Decl *decl) {
41984198 } else if (auto *genericDecl = dyn_cast<GenericTypeDecl>(decl)) {
41994199 checkExistentialTypes (ctx, genericDecl->getGenericParams ());
42004200 checkExistentialTypes (ctx, genericDecl->getTrailingWhereClause ());
4201+ if (auto *typeAlias = dyn_cast<TypeAliasDecl>(decl)) {
4202+ checkExistentialTypes (ctx, typeAlias);
4203+ }
42014204 } else if (auto *assocType = dyn_cast<AssociatedTypeDecl>(decl)) {
42024205 checkExistentialTypes (ctx, assocType->getTrailingWhereClause ());
42034206 } else if (auto *extDecl = dyn_cast<ExtensionDecl>(decl)) {
@@ -4227,6 +4230,19 @@ void TypeChecker::checkExistentialTypes(ASTContext &ctx, Stmt *stmt) {
42274230 stmt->walk (visitor);
42284231}
42294232
4233+ void TypeChecker::checkExistentialTypes (ASTContext &ctx,
4234+ TypeAliasDecl *typeAlias) {
4235+ if (!typeAlias || !typeAlias->getUnderlyingTypeRepr ())
4236+ return ;
4237+
4238+ // A type alias to a plain constraint type is allowed.
4239+ if (typeAlias->getUnderlyingType ()->isConstraintType ())
4240+ return ;
4241+
4242+ ExistentialTypeVisitor visitor (ctx, /* checkStatements=*/ true );
4243+ typeAlias->getUnderlyingTypeRepr ()->walk (visitor);
4244+ }
4245+
42304246void TypeChecker::checkExistentialTypes (
42314247 ASTContext &ctx, TrailingWhereClause *whereClause) {
42324248 if (whereClause == nullptr )
0 commit comments