@@ -3950,6 +3950,10 @@ class ExistentialTypeVisitor
3950
3950
// Arbitrary protocol constraints are OK on opaque types.
3951
3951
if (isa<OpaqueReturnTypeRepr>(T))
3952
3952
return false ;
3953
+
3954
+ // Arbitrary protocol constraints are okay for 'any' types.
3955
+ if (isa<ExistentialTypeRepr>(T))
3956
+ return false ;
3953
3957
3954
3958
visit (T);
3955
3959
return true ;
@@ -3973,7 +3977,36 @@ class ExistentialTypeVisitor
3973
3977
}
3974
3978
3975
3979
void visitIdentTypeRepr (IdentTypeRepr *T) {
3976
- return ;
3980
+ if (T->isInvalid () || !Ctx.LangOpts .EnableExplicitExistentialTypes )
3981
+ return ;
3982
+
3983
+ auto comp = T->getComponentRange ().back ();
3984
+ if (auto *proto = dyn_cast_or_null<ProtocolDecl>(comp->getBoundDecl ())) {
3985
+ if (proto->existentialRequiresAny ()) {
3986
+ Ctx.Diags .diagnose (comp->getNameLoc (),
3987
+ diag::existential_requires_any,
3988
+ proto->getName ());
3989
+ }
3990
+ } else if (auto *alias = dyn_cast_or_null<TypeAliasDecl>(comp->getBoundDecl ())) {
3991
+ auto type = Type (alias->getDeclaredInterfaceType ()->getDesugaredType ());
3992
+ type.findIf ([&](Type type) -> bool {
3993
+ if (T->isInvalid ())
3994
+ return false ;
3995
+ if (type->isExistentialType ()) {
3996
+ auto layout = type->getExistentialLayout ();
3997
+ for (auto *proto : layout.getProtocols ()) {
3998
+ auto *protoDecl = proto->getDecl ();
3999
+ if (!protoDecl->existentialRequiresAny ())
4000
+ continue ;
4001
+
4002
+ Ctx.Diags .diagnose (comp->getNameLoc (),
4003
+ diag::existential_requires_any,
4004
+ protoDecl->getName ());
4005
+ }
4006
+ }
4007
+ return false ;
4008
+ });
4009
+ }
3977
4010
}
3978
4011
3979
4012
void visitRequirements (ArrayRef<RequirementRepr> reqts) {
0 commit comments