@@ -4154,29 +4154,29 @@ class ExistentialTypeVisitor
41544154 if (proto->existentialRequiresAny ()) {
41554155 Ctx.Diags .diagnose (comp->getNameLoc (),
41564156 diag::existential_requires_any,
4157- proto->getName ())
4157+ proto->getDeclaredInterfaceType (),
4158+ /* isAlias=*/ false )
41584159 .limitBehavior (DiagnosticBehavior::Warning);
41594160 }
41604161 } else if (auto *alias = dyn_cast_or_null<TypeAliasDecl>(comp->getBoundDecl ())) {
41614162 auto type = Type (alias->getDeclaredInterfaceType ()->getDesugaredType ());
4162- type. findIf ([&](Type type) -> bool {
4163- if (T-> isInvalid ())
4164- return false ;
4165- if (type->isExistentialType ()) {
4166- auto layout = type->getExistentialLayout ();
4167- for (auto *proto : layout.getProtocols ()) {
4168- auto *protoDecl = proto->getDecl ();
4169- if (!protoDecl->existentialRequiresAny ())
4170- continue ;
4163+ // If this is a type alias to a constraint type, the type
4164+ // alias name must be prefixed with 'any' to be used as an
4165+ // existential type.
4166+ if (type->isConstraintType ()) {
4167+ auto layout = type->getExistentialLayout ();
4168+ for (auto *proto : layout.getProtocols ()) {
4169+ auto *protoDecl = proto->getDecl ();
4170+ if (!protoDecl->existentialRequiresAny ())
4171+ continue ;
41714172
4172- Ctx.Diags .diagnose (comp->getNameLoc (),
4173- diag::existential_requires_any,
4174- protoDecl-> getName ())
4175- . limitBehavior (DiagnosticBehavior::Warning);
4176- }
4173+ Ctx.Diags .diagnose (comp->getNameLoc (),
4174+ diag::existential_requires_any,
4175+ alias-> getDeclaredInterfaceType (),
4176+ /* isAlias= */ true )
4177+ . limitBehavior (DiagnosticBehavior::Warning);
41774178 }
4178- return false ;
4179- });
4179+ }
41804180 }
41814181 }
41824182
@@ -4204,6 +4204,9 @@ void TypeChecker::checkExistentialTypes(Decl *decl) {
42044204 } else if (auto *genericDecl = dyn_cast<GenericTypeDecl>(decl)) {
42054205 checkExistentialTypes (ctx, genericDecl->getGenericParams ());
42064206 checkExistentialTypes (ctx, genericDecl->getTrailingWhereClause ());
4207+ if (auto *typeAlias = dyn_cast<TypeAliasDecl>(decl)) {
4208+ checkExistentialTypes (ctx, typeAlias);
4209+ }
42074210 } else if (auto *assocType = dyn_cast<AssociatedTypeDecl>(decl)) {
42084211 checkExistentialTypes (ctx, assocType->getTrailingWhereClause ());
42094212 } else if (auto *extDecl = dyn_cast<ExtensionDecl>(decl)) {
@@ -4233,6 +4236,19 @@ void TypeChecker::checkExistentialTypes(ASTContext &ctx, Stmt *stmt) {
42334236 stmt->walk (visitor);
42344237}
42354238
4239+ void TypeChecker::checkExistentialTypes (ASTContext &ctx,
4240+ TypeAliasDecl *typeAlias) {
4241+ if (!typeAlias || !typeAlias->getUnderlyingTypeRepr ())
4242+ return ;
4243+
4244+ // A type alias to a plain constraint type is allowed.
4245+ if (typeAlias->getUnderlyingType ()->isConstraintType ())
4246+ return ;
4247+
4248+ ExistentialTypeVisitor visitor (ctx, /* checkStatements=*/ true );
4249+ typeAlias->getUnderlyingTypeRepr ()->walk (visitor);
4250+ }
4251+
42364252void TypeChecker::checkExistentialTypes (
42374253 ASTContext &ctx, TrailingWhereClause *whereClause) {
42384254 if (whereClause == nullptr )
0 commit comments