@@ -3943,6 +3943,128 @@ Type TypeChecker::substMemberTypeWithBase(ModuleDecl *module,
3943
3943
return resultType;
3944
3944
}
3945
3945
3946
+ namespace {
3947
+
3948
+ class UnsupportedProtocolVisitor
3949
+ : public TypeReprVisitor<UnsupportedProtocolVisitor>, public ASTWalker
3950
+ {
3951
+ ASTContext &Ctx;
3952
+ bool checkStatements;
3953
+ bool hitTopStmt;
3954
+
3955
+ public:
3956
+ UnsupportedProtocolVisitor (ASTContext &ctx, bool checkStatements)
3957
+ : Ctx(ctx), checkStatements(checkStatements), hitTopStmt(false ) { }
3958
+
3959
+ bool walkToTypeReprPre (TypeRepr *T) override {
3960
+ if (T->isInvalid ())
3961
+ return false ;
3962
+ if (auto compound = dyn_cast<CompoundIdentTypeRepr>(T)) {
3963
+ // Only visit the last component to check, because nested typealiases in
3964
+ // existentials are okay.
3965
+ visit (compound->getComponentRange ().back ());
3966
+ return false ;
3967
+ }
3968
+ // Arbitrary protocol constraints are OK on opaque types.
3969
+ if (isa<OpaqueReturnTypeRepr>(T))
3970
+ return false ;
3971
+
3972
+ visit (T);
3973
+ return true ;
3974
+ }
3975
+
3976
+ std::pair<bool , Stmt*> walkToStmtPre (Stmt *S) override {
3977
+ if (checkStatements && !hitTopStmt) {
3978
+ hitTopStmt = true ;
3979
+ return { true , S };
3980
+ }
3981
+
3982
+ return { false , S };
3983
+ }
3984
+
3985
+ bool walkToDeclPre (Decl *D) override {
3986
+ return !checkStatements;
3987
+ }
3988
+
3989
+ void visitTypeRepr (TypeRepr *T) {
3990
+ // Do nothing for all TypeReprs except the ones listed below.
3991
+ }
3992
+
3993
+ void visitIdentTypeRepr (IdentTypeRepr *T) {
3994
+ return ;
3995
+ }
3996
+
3997
+ void visitRequirements (ArrayRef<RequirementRepr> reqts) {
3998
+ for (auto reqt : reqts) {
3999
+ if (reqt.getKind () == RequirementReprKind::SameType) {
4000
+ if (auto *repr = reqt.getFirstTypeRepr ())
4001
+ repr->walk (*this );
4002
+ if (auto *repr = reqt.getSecondTypeRepr ())
4003
+ repr->walk (*this );
4004
+ }
4005
+ }
4006
+ }
4007
+ };
4008
+
4009
+ } // end anonymous namespace
4010
+
4011
+ void TypeChecker::checkUnsupportedProtocolType (Decl *decl) {
4012
+ if (!decl || decl->isInvalid ())
4013
+ return ;
4014
+
4015
+ auto &ctx = decl->getASTContext ();
4016
+ if (auto *protocolDecl = dyn_cast<ProtocolDecl>(decl)) {
4017
+ checkUnsupportedProtocolType (ctx, protocolDecl->getTrailingWhereClause ());
4018
+ } else if (auto *genericDecl = dyn_cast<GenericTypeDecl>(decl)) {
4019
+ checkUnsupportedProtocolType (ctx, genericDecl->getGenericParams ());
4020
+ checkUnsupportedProtocolType (ctx, genericDecl->getTrailingWhereClause ());
4021
+ } else if (auto *assocType = dyn_cast<AssociatedTypeDecl>(decl)) {
4022
+ checkUnsupportedProtocolType (ctx, assocType->getTrailingWhereClause ());
4023
+ } else if (auto *extDecl = dyn_cast<ExtensionDecl>(decl)) {
4024
+ checkUnsupportedProtocolType (ctx, extDecl->getTrailingWhereClause ());
4025
+ } else if (auto *subscriptDecl = dyn_cast<SubscriptDecl>(decl)) {
4026
+ checkUnsupportedProtocolType (ctx, subscriptDecl->getGenericParams ());
4027
+ checkUnsupportedProtocolType (ctx, subscriptDecl->getTrailingWhereClause ());
4028
+ } else if (auto *funcDecl = dyn_cast<AbstractFunctionDecl>(decl)) {
4029
+ if (!isa<AccessorDecl>(funcDecl)) {
4030
+ checkUnsupportedProtocolType (ctx, funcDecl->getGenericParams ());
4031
+ checkUnsupportedProtocolType (ctx, funcDecl->getTrailingWhereClause ());
4032
+ }
4033
+ }
4034
+
4035
+ if (isa<TypeDecl>(decl) || isa<ExtensionDecl>(decl))
4036
+ return ;
4037
+
4038
+ UnsupportedProtocolVisitor visitor (ctx, /* checkStatements=*/ false );
4039
+ decl->walk (visitor);
4040
+ }
4041
+
4042
+ void TypeChecker::checkUnsupportedProtocolType (ASTContext &ctx, Stmt *stmt) {
4043
+ if (!stmt)
4044
+ return ;
4045
+
4046
+ UnsupportedProtocolVisitor visitor (ctx, /* checkStatements=*/ true );
4047
+ stmt->walk (visitor);
4048
+ }
4049
+
4050
+ void TypeChecker::checkUnsupportedProtocolType (
4051
+ ASTContext &ctx, TrailingWhereClause *whereClause) {
4052
+ if (whereClause == nullptr )
4053
+ return ;
4054
+
4055
+ UnsupportedProtocolVisitor visitor (ctx, /* checkStatements=*/ false );
4056
+ visitor.visitRequirements (whereClause->getRequirements ());
4057
+ }
4058
+
4059
+ void TypeChecker::checkUnsupportedProtocolType (
4060
+ ASTContext &ctx, GenericParamList *genericParams) {
4061
+ if (genericParams == nullptr )
4062
+ return ;
4063
+
4064
+ UnsupportedProtocolVisitor visitor (ctx, /* checkStatements=*/ false );
4065
+ visitor.visitRequirements (genericParams->getRequirements ());
4066
+ }
4067
+
3946
4068
Type CustomAttrTypeRequest::evaluate (Evaluator &eval, CustomAttr *attr,
3947
4069
DeclContext *dc,
3948
4070
CustomAttrTypeKind typeKind) const {
0 commit comments