Skip to content

Commit 110fbdd

Browse files
committed
[SE-0306] Ban "class" methods and properties in actors.
Within actors, one should use "static", not "class". Fixes rdar://80285441. (cherry picked from commit 2bb94f8)
1 parent b3efbc3 commit 110fbdd

File tree

5 files changed

+40
-4
lines changed

5 files changed

+40
-4
lines changed

lib/AST/Decl.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1595,10 +1595,12 @@ SourceRange PatternBindingDecl::getSourceRange() const {
15951595
}
15961596

15971597
static StaticSpellingKind getCorrectStaticSpellingForDecl(const Decl *D) {
1598-
if (!D->getDeclContext()->getSelfClassDecl())
1599-
return StaticSpellingKind::KeywordStatic;
1598+
if (auto classDecl = D->getDeclContext()->getSelfClassDecl()) {
1599+
if (!classDecl->isActor())
1600+
return StaticSpellingKind::KeywordClass;
1601+
}
16001602

1601-
return StaticSpellingKind::KeywordClass;
1603+
return StaticSpellingKind::KeywordStatic;
16021604
}
16031605

16041606
StaticSpellingKind PatternBindingDecl::getCorrectStaticSpelling() const {

lib/Sema/TypeCheckDeclPrimary.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2645,6 +2645,14 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
26452645
}
26462646
}
26472647

2648+
// Reject "class" methods on actors.
2649+
if (StaticSpelling == StaticSpellingKind::KeywordClass &&
2650+
FD->getDeclContext()->getSelfClassDecl() &&
2651+
FD->getDeclContext()->getSelfClassDecl()->isActor()) {
2652+
FD->diagnose(diag::class_func_not_in_class, false)
2653+
.fixItReplace(FD->getStaticLoc(), "static");
2654+
}
2655+
26482656
// Member functions need some special validation logic.
26492657
if (FD->getDeclContext()->isTypeContext()) {
26502658
if (FD->isOperator() && !isMemberOperator(FD, nullptr)) {

lib/Sema/TypeCheckStorage.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,14 @@ PatternBindingEntryRequest::evaluate(Evaluator &eval,
219219
}
220220
}
221221

222+
// Reject "class" methods on actors.
223+
if (StaticSpelling == StaticSpellingKind::KeywordClass &&
224+
binding->getDeclContext()->getSelfClassDecl() &&
225+
binding->getDeclContext()->getSelfClassDecl()->isActor()) {
226+
binding->diagnose(diag::class_var_not_in_class, false)
227+
.fixItReplace(binding->getStaticLoc(), "static");
228+
}
229+
222230
// Check the pattern.
223231
auto contextualPattern =
224232
ContextualPattern::forPatternBindingDecl(binding, entryNumber);

test/Concurrency/actor_isolation.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ actor MyActor: MySuperActor { // expected-error{{actor types do not support inhe
7171
return self.name // expected-error{{property 'name' isolated to global actor 'MainActor' can not be referenced from actor 'MyActor' in a synchronous context}}
7272
}
7373

74-
class func synchronousClass() { }
74+
static func synchronousClass() { }
7575
static func synchronousStatic() { }
7676

7777
func synchronous() -> String { text.first ?? "nothing" } // expected-note 9{{calls to instance method 'synchronous()' from outside of its actor context are implicitly asynchronous}}

test/decl/class/actor/basic.swift

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,21 @@ actor public class BarbraStreisand {}
2727
public actor struct JulieAndrews {}
2828
// expected-error@+1{{keyword 'public' cannot be used as an identifier here}}
2929
actor public enum TomHanks {}
30+
31+
open actor A1 { } // expected-error{{only classes and overridable class members can be declared 'open'; use 'public'}}
32+
33+
actor A2 {
34+
required init() { } // expected-error{{'required' initializer in non-class type 'A2'}}
35+
open func f() { } // expected-error{{only classes and overridable class members can be declared 'open'; use 'public'}}
36+
37+
final func g() { } // okay for now
38+
class func h() { } // expected-error{{class methods are only allowed within classes; use 'static' to declare a static method}}
39+
static func i() { } // okay
40+
41+
class var someProp: Int { 0 } // expected-error{{class properties are only allowed within classes; use 'static' to declare a static property}}
42+
}
43+
44+
extension A2 {
45+
class func h2() { } // expected-error{{class methods are only allowed within classes; use 'static' to declare a static method}}
46+
static func i2() { } // okay
47+
}

0 commit comments

Comments
 (0)