Skip to content

Commit 9651247

Browse files
committed
Better error message for 'class func/var' usage in protocols
1 parent feb3857 commit 9651247

File tree

5 files changed

+21
-10
lines changed

5 files changed

+21
-10
lines changed

include/swift/AST/DiagnosticsCommon.def

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,10 +66,10 @@ ERROR(super_not_in_class_method,none,
6666

6767
ERROR(class_func_not_in_class,none,
6868
"class methods are only allowed within classes; "
69-
"use 'static' to declare a static method", ())
69+
"use 'static' to declare a%select{| requirement fulfilled by either a class or}0 static method", (bool))
7070
ERROR(class_var_not_in_class,none,
7171
"class properties are only allowed within classes; "
72-
"use 'static' to declare a static property", ())
72+
"use 'static' to declare a%select{| requirement fulfilled by either a class or}0 static property", (bool))
7373

7474
// FIXME: Used by both the parser and the type-checker.
7575
ERROR(func_decl_without_brace,PointsToFirstBadToken,

lib/Parse/ParseDecl.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4808,7 +4808,8 @@ Parser::parseDeclVar(ParseDeclOptions Flags,
48084808
} else if (Flags.contains(PD_InStruct) || Flags.contains(PD_InEnum) ||
48094809
Flags.contains(PD_InProtocol)) {
48104810
if (StaticSpelling == StaticSpellingKind::KeywordClass)
4811-
diagnose(Tok, diag::class_var_not_in_class)
4811+
diagnose(Tok, diag::class_var_not_in_class,
4812+
Flags.contains(PD_InProtocol))
48124813
.fixItReplace(StaticLoc, "static");
48134814
}
48144815
}
@@ -5194,7 +5195,8 @@ Parser::parseDeclFunc(SourceLoc StaticLoc, StaticSpellingKind StaticSpelling,
51945195
} else if (Flags.contains(PD_InStruct) || Flags.contains(PD_InEnum) ||
51955196
Flags.contains(PD_InProtocol)) {
51965197
if (StaticSpelling == StaticSpellingKind::KeywordClass) {
5197-
diagnose(Tok, diag::class_func_not_in_class)
5198+
diagnose(Tok, diag::class_func_not_in_class,
5199+
Flags.contains(PD_InProtocol))
51985200
.fixItReplace(StaticLoc, "static");
51995201

52005202
StaticSpelling = StaticSpellingKind::KeywordStatic;

lib/Sema/TypeCheckDecl.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1134,7 +1134,7 @@ static void validatePatternBindingEntry(TypeChecker &tc,
11341134
->getAsNominalTypeOrNominalTypeExtensionContext()) {
11351135
if (!isa<ClassDecl>(NTD)) {
11361136
if (StaticSpelling == StaticSpellingKind::KeywordClass) {
1137-
tc.diagnose(binding, diag::class_var_not_in_class)
1137+
tc.diagnose(binding, diag::class_var_not_in_class, false)
11381138
.fixItReplace(binding->getStaticLoc(), "static");
11391139
tc.diagnose(NTD, diag::extended_type_declared_here);
11401140
}
@@ -7194,7 +7194,7 @@ void TypeChecker::validateDecl(ValueDecl *D) {
71947194
->getAsNominalTypeOrNominalTypeExtensionContext()) {
71957195
if (!isa<ClassDecl>(NTD)) {
71967196
if (StaticSpelling == StaticSpellingKind::KeywordClass) {
7197-
diagnose(FD, diag::class_func_not_in_class)
7197+
diagnose(FD, diag::class_func_not_in_class, false)
71987198
.fixItReplace(FD->getStaticLoc(), "static");
71997199
diagnose(NTD, diag::extended_type_declared_here);
72007200
}

test/decl/func/static_func.swift

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,10 +105,15 @@ extension C_Derived {
105105
class override func ef5() {} // expected-error {{not supported}}
106106
}
107107

108-
protocol P {
108+
protocol P { // expected-note{{extended type declared here}}
109109
static func f1()
110110
static func f2()
111111
static func f3() {} // expected-error {{protocol methods must not have bodies}}
112112
static final func f4() // expected-error {{only classes and class members may be marked with 'final'}}
113+
class func f5() // expected-error {{class methods are only allowed within classes; use 'static' to declare a requirement fulfilled by either a class or static method}} {{3-8=static}}
114+
}
115+
116+
extension P {
117+
class func f6() {} // expected-error {{class methods are only allowed within classes; use 'static' to declare a static method}} {{3-8=static}}
113118
}
114119

test/decl/var/static_var.swift

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -171,14 +171,18 @@ extension C {
171171
static final let el4: Int = 0 // expected-error {{static declarations are already final}} {{10-16=}}
172172
}
173173

174-
protocol P { // expected-note{{did you mean 'P'?}}
174+
protocol P { // expected-note{{did you mean 'P'?}} expected-note{{extended type declared here}}
175175
// Both `static` and `class` property requirements are equivalent in protocols rdar://problem/17198298
176176
static var v1: Int { get }
177-
class var v2: Int { get } // expected-error {{class properties are only allowed within classes; use 'static' to declare a static property}} {{3-8=static}}
177+
class var v2: Int { get } // expected-error {{class properties are only allowed within classes; use 'static' to declare a requirement fulfilled by either a class or static property}} {{3-8=static}}
178178
static final var v3: Int { get } // expected-error {{only classes and class members may be marked with 'final'}}
179179

180180
static let l1: Int // expected-error {{immutable property requirement must be declared as 'var' with a '{ get }' specifier}}
181-
class let l2: Int // expected-error {{class properties are only allowed within classes; use 'static' to declare a static property}} {{3-8=static}} expected-error {{immutable property requirement must be declared as 'var' with a '{ get }' specifier}}
181+
class let l2: Int // expected-error {{class properties are only allowed within classes; use 'static' to declare a requirement fulfilled by either a class or static property}} {{3-8=static}} expected-error {{immutable property requirement must be declared as 'var' with a '{ get }' specifier}}
182+
}
183+
184+
extension P {
185+
class var v4: Int { return 0 } // expected-error {{class properties are only allowed within classes; use 'static' to declare a static property}} {{3-8=static}}
182186
}
183187

184188
struct S1 {

0 commit comments

Comments
 (0)