@@ -4148,29 +4148,29 @@ class ExistentialTypeVisitor
4148
4148
if (proto->existentialRequiresAny ()) {
4149
4149
Ctx.Diags .diagnose (comp->getNameLoc (),
4150
4150
diag::existential_requires_any,
4151
- proto->getName ())
4151
+ proto->getDeclaredInterfaceType (),
4152
+ /* isAlias=*/ false )
4152
4153
.limitBehavior (DiagnosticBehavior::Warning);
4153
4154
}
4154
4155
} else if (auto *alias = dyn_cast_or_null<TypeAliasDecl>(comp->getBoundDecl ())) {
4155
4156
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 ;
4165
4166
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);
4171
4172
}
4172
- return false ;
4173
- });
4173
+ }
4174
4174
}
4175
4175
}
4176
4176
@@ -4198,6 +4198,9 @@ void TypeChecker::checkExistentialTypes(Decl *decl) {
4198
4198
} else if (auto *genericDecl = dyn_cast<GenericTypeDecl>(decl)) {
4199
4199
checkExistentialTypes (ctx, genericDecl->getGenericParams ());
4200
4200
checkExistentialTypes (ctx, genericDecl->getTrailingWhereClause ());
4201
+ if (auto *typeAlias = dyn_cast<TypeAliasDecl>(decl)) {
4202
+ checkExistentialTypes (ctx, typeAlias);
4203
+ }
4201
4204
} else if (auto *assocType = dyn_cast<AssociatedTypeDecl>(decl)) {
4202
4205
checkExistentialTypes (ctx, assocType->getTrailingWhereClause ());
4203
4206
} else if (auto *extDecl = dyn_cast<ExtensionDecl>(decl)) {
@@ -4227,6 +4230,19 @@ void TypeChecker::checkExistentialTypes(ASTContext &ctx, Stmt *stmt) {
4227
4230
stmt->walk (visitor);
4228
4231
}
4229
4232
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
+
4230
4246
void TypeChecker::checkExistentialTypes (
4231
4247
ASTContext &ctx, TrailingWhereClause *whereClause) {
4232
4248
if (whereClause == nullptr )
0 commit comments