@@ -1240,8 +1240,21 @@ IsFinalRequest::evaluate(Evaluator &evaluator, ValueDecl *decl) const {
1240
1240
1241
1241
llvm::Expected<bool >
1242
1242
IsStaticRequest::evaluate (Evaluator &evaluator, FuncDecl *decl) const {
1243
- return (decl->getStaticLoc ().isValid () ||
1244
- decl->getStaticSpelling () != StaticSpellingKind::None);
1243
+ bool result = (decl->getStaticLoc ().isValid () ||
1244
+ decl->getStaticSpelling () != StaticSpellingKind::None);
1245
+ auto *dc = decl->getDeclContext ();
1246
+ if (!result &&
1247
+ decl->isOperator () &&
1248
+ dc->isTypeContext ()) {
1249
+ auto operatorName = decl->getFullName ().getBaseIdentifier ();
1250
+ decl->diagnose (diag::nonstatic_operator_in_type,
1251
+ operatorName, dc->getDeclaredInterfaceType ())
1252
+ .fixItInsert (decl->getAttributeInsertionLoc (/* forModifier=*/ true ),
1253
+ " static " );
1254
+ result = true ;
1255
+ }
1256
+
1257
+ return result;
1245
1258
}
1246
1259
1247
1260
llvm::Expected<bool >
@@ -3070,7 +3083,9 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
3070
3083
}
3071
3084
3072
3085
void visitFuncDecl (FuncDecl *FD) {
3073
- (void )FD->getInterfaceType ();
3086
+ // Force these requests in case they emit diagnostics.
3087
+ (void ) FD->getInterfaceType ();
3088
+ (void ) FD->getOperatorDecl ();
3074
3089
3075
3090
if (!FD->isInvalid ()) {
3076
3091
checkGenericParams (FD->getGenericParams (), FD, TC);
@@ -3114,6 +3129,33 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
3114
3129
checkDynamicSelfType (FD, FD->getResultInterfaceType ());
3115
3130
3116
3131
checkDefaultArguments (TC, FD->getParameters (), FD);
3132
+
3133
+ // Validate 'static'/'class' on functions in extensions.
3134
+ auto StaticSpelling = FD->getStaticSpelling ();
3135
+ if (StaticSpelling != StaticSpellingKind::None &&
3136
+ isa<ExtensionDecl>(FD->getDeclContext ())) {
3137
+ if (auto *NTD = FD->getDeclContext ()->getSelfNominalTypeDecl ()) {
3138
+ if (!isa<ClassDecl>(NTD)) {
3139
+ if (StaticSpelling == StaticSpellingKind::KeywordClass) {
3140
+ FD->diagnose (diag::class_func_not_in_class, false )
3141
+ .fixItReplace (FD->getStaticLoc (), " static" );
3142
+ NTD->diagnose (diag::extended_type_declared_here);
3143
+ }
3144
+ }
3145
+ }
3146
+ }
3147
+
3148
+ // Member functions need some special validation logic.
3149
+ if (FD->getDeclContext ()->isTypeContext ()) {
3150
+ if (FD->isOperator () && !isMemberOperator (FD, nullptr )) {
3151
+ auto selfNominal = FD->getDeclContext ()->getSelfNominalTypeDecl ();
3152
+ auto isProtocol = selfNominal && isa<ProtocolDecl>(selfNominal);
3153
+ // We did not find 'Self'. Complain.
3154
+ FD->diagnose (diag::operator_in_unrelated_type,
3155
+ FD->getDeclContext ()->getDeclaredInterfaceType (), isProtocol,
3156
+ FD->getFullName ());
3157
+ }
3158
+ }
3117
3159
}
3118
3160
3119
3161
void visitModuleDecl (ModuleDecl *) { }
@@ -3604,16 +3646,10 @@ FunctionOperatorRequest::evaluate(Evaluator &evaluator, FuncDecl *FD) const {
3604
3646
// Check for static/final/class when we're in a type.
3605
3647
auto dc = FD->getDeclContext ();
3606
3648
if (dc->isTypeContext ()) {
3607
- if (!FD->isStatic ()) {
3608
- FD->diagnose (diag::nonstatic_operator_in_type,
3609
- operatorName, dc->getDeclaredInterfaceType ())
3610
- .fixItInsert (FD->getAttributeInsertionLoc (/* forModifier=*/ true ),
3611
- " static " );
3612
-
3613
- FD->setStatic ();
3614
- } else if (auto classDecl = dc->getSelfClassDecl ()) {
3649
+ if (auto classDecl = dc->getSelfClassDecl ()) {
3615
3650
// For a class, we also need the function or class to be 'final'.
3616
3651
if (!classDecl->isFinal () && !FD->isFinal () &&
3652
+ FD->getStaticLoc ().isValid () &&
3617
3653
FD->getStaticSpelling () != StaticSpellingKind::KeywordStatic) {
3618
3654
FD->diagnose (diag::nonfinal_operator_in_class,
3619
3655
operatorName, dc->getDeclaredInterfaceType ())
@@ -3987,24 +4023,6 @@ void TypeChecker::validateDecl(ValueDecl *D) {
3987
4023
3988
4024
DeclValidationRAII IBV (FD);
3989
4025
3990
- // Force computing the operator decl in case it emits diagnostics.
3991
- (void ) FD->getOperatorDecl ();
3992
-
3993
- // Validate 'static'/'class' on functions in extensions.
3994
- auto StaticSpelling = FD->getStaticSpelling ();
3995
- if (StaticSpelling != StaticSpellingKind::None &&
3996
- isa<ExtensionDecl>(FD->getDeclContext ())) {
3997
- if (auto *NTD = FD->getDeclContext ()->getSelfNominalTypeDecl ()) {
3998
- if (!isa<ClassDecl>(NTD)) {
3999
- if (StaticSpelling == StaticSpellingKind::KeywordClass) {
4000
- diagnose (FD, diag::class_func_not_in_class, false )
4001
- .fixItReplace (FD->getStaticLoc (), " static" );
4002
- diagnose (NTD, diag::extended_type_declared_here);
4003
- }
4004
- }
4005
- }
4006
- }
4007
-
4008
4026
// Accessors should pick up various parts of their type signatures
4009
4027
// directly from the storage declaration instead of re-deriving them.
4010
4028
// FIXME: should this include the generic signature?
@@ -4086,18 +4104,6 @@ void TypeChecker::validateDecl(ValueDecl *D) {
4086
4104
// FIXME: Roll all of this interface type computation into a request.
4087
4105
FD->computeType ();
4088
4106
4089
- // Member functions need some special validation logic.
4090
- if (FD->getDeclContext ()->isTypeContext ()) {
4091
- if (FD->isOperator () && !isMemberOperator (FD, nullptr )) {
4092
- auto selfNominal = FD->getDeclContext ()->getSelfNominalTypeDecl ();
4093
- auto isProtocol = selfNominal && isa<ProtocolDecl>(selfNominal);
4094
- // We did not find 'Self'. Complain.
4095
- diagnose (FD, diag::operator_in_unrelated_type,
4096
- FD->getDeclContext ()->getDeclaredInterfaceType (), isProtocol,
4097
- FD->getFullName ());
4098
- }
4099
- }
4100
-
4101
4107
// If the function is exported to C, it must be representable in (Obj-)C.
4102
4108
if (auto CDeclAttr = FD->getAttrs ().getAttribute <swift::CDeclAttr>()) {
4103
4109
Optional<ForeignErrorConvention> errorConvention;
0 commit comments