@@ -3968,6 +3968,10 @@ class ExistentialTypeVisitor
3968
3968
// Arbitrary protocol constraints are OK on opaque types.
3969
3969
if (isa<OpaqueReturnTypeRepr>(T))
3970
3970
return false ;
3971
+
3972
+ // Arbitrary protocol constraints are okay for 'any' types.
3973
+ if (isa<ExistentialTypeRepr>(T))
3974
+ return false ;
3971
3975
3972
3976
visit (T);
3973
3977
return true ;
@@ -3991,7 +3995,36 @@ class ExistentialTypeVisitor
3991
3995
}
3992
3996
3993
3997
void visitIdentTypeRepr (IdentTypeRepr *T) {
3994
- return ;
3998
+ if (T->isInvalid () || !Ctx.LangOpts .EnableExplicitExistentialTypes )
3999
+ return ;
4000
+
4001
+ auto comp = T->getComponentRange ().back ();
4002
+ if (auto *proto = dyn_cast_or_null<ProtocolDecl>(comp->getBoundDecl ())) {
4003
+ if (proto->existentialRequiresAny ()) {
4004
+ Ctx.Diags .diagnose (comp->getNameLoc (),
4005
+ diag::existential_requires_any,
4006
+ proto->getName ());
4007
+ }
4008
+ } else if (auto *alias = dyn_cast_or_null<TypeAliasDecl>(comp->getBoundDecl ())) {
4009
+ auto type = Type (alias->getDeclaredInterfaceType ()->getDesugaredType ());
4010
+ type.findIf ([&](Type type) -> bool {
4011
+ if (T->isInvalid ())
4012
+ return false ;
4013
+ if (type->isExistentialType ()) {
4014
+ auto layout = type->getExistentialLayout ();
4015
+ for (auto *proto : layout.getProtocols ()) {
4016
+ auto *protoDecl = proto->getDecl ();
4017
+ if (!protoDecl->existentialRequiresAny ())
4018
+ continue ;
4019
+
4020
+ Ctx.Diags .diagnose (comp->getNameLoc (),
4021
+ diag::existential_requires_any,
4022
+ protoDecl->getName ());
4023
+ }
4024
+ }
4025
+ return false ;
4026
+ });
4027
+ }
3995
4028
}
3996
4029
3997
4030
void visitRequirements (ArrayRef<RequirementRepr> reqts) {
0 commit comments