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