@@ -4154,29 +4154,29 @@ class ExistentialTypeVisitor
4154
4154
if (proto->existentialRequiresAny ()) {
4155
4155
Ctx.Diags .diagnose (comp->getNameLoc (),
4156
4156
diag::existential_requires_any,
4157
- proto->getName ())
4157
+ proto->getDeclaredInterfaceType (),
4158
+ /* isAlias=*/ false )
4158
4159
.limitBehavior (DiagnosticBehavior::Warning);
4159
4160
}
4160
4161
} else if (auto *alias = dyn_cast_or_null<TypeAliasDecl>(comp->getBoundDecl ())) {
4161
4162
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 ;
4171
4172
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);
4177
4178
}
4178
- return false ;
4179
- });
4179
+ }
4180
4180
}
4181
4181
}
4182
4182
@@ -4204,6 +4204,9 @@ void TypeChecker::checkExistentialTypes(Decl *decl) {
4204
4204
} else if (auto *genericDecl = dyn_cast<GenericTypeDecl>(decl)) {
4205
4205
checkExistentialTypes (ctx, genericDecl->getGenericParams ());
4206
4206
checkExistentialTypes (ctx, genericDecl->getTrailingWhereClause ());
4207
+ if (auto *typeAlias = dyn_cast<TypeAliasDecl>(decl)) {
4208
+ checkExistentialTypes (ctx, typeAlias);
4209
+ }
4207
4210
} else if (auto *assocType = dyn_cast<AssociatedTypeDecl>(decl)) {
4208
4211
checkExistentialTypes (ctx, assocType->getTrailingWhereClause ());
4209
4212
} else if (auto *extDecl = dyn_cast<ExtensionDecl>(decl)) {
@@ -4233,6 +4236,19 @@ void TypeChecker::checkExistentialTypes(ASTContext &ctx, Stmt *stmt) {
4233
4236
stmt->walk (visitor);
4234
4237
}
4235
4238
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
+
4236
4252
void TypeChecker::checkExistentialTypes (
4237
4253
ASTContext &ctx, TrailingWhereClause *whereClause) {
4238
4254
if (whereClause == nullptr )
0 commit comments