Skip to content

Commit 42d1c07

Browse files
authored
Merge pull request swiftlang#35342 from DougGregor/infer-actor-only-instance-members
[Concurrency] Only infer extension/nominal actor for instance members.
2 parents 80a9df2 + af94871 commit 42d1c07

File tree

3 files changed

+41
-22
lines changed

3 files changed

+41
-22
lines changed

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -834,7 +834,7 @@ namespace {
834834
}
835835
}
836836

837-
// The children of #selector expressions are not evaluation, so we do not
837+
// The children of #selector expressions are not evaluated, so we do not
838838
// need to do isolation checking there. This is convenient because such
839839
// expressions tend to violate restrictions on the use of instance
840840
// methods.
@@ -1886,20 +1886,23 @@ ActorIsolation ActorIsolationRequest::evaluate(
18861886
}
18871887
}
18881888

1889-
// If the declaration is in an extension that has one of the isolation
1890-
// attributes, use that.
1891-
if (auto ext = dyn_cast<ExtensionDecl>(value->getDeclContext())) {
1892-
if (auto isolationFromAttr = getIsolationFromAttributes(ext)) {
1893-
return inferredIsolation(*isolationFromAttr);
1889+
// Instance members can infer isolation from their context.
1890+
if (value->isInstanceMember()) {
1891+
// If the declaration is in an extension that has one of the isolation
1892+
// attributes, use that.
1893+
if (auto ext = dyn_cast<ExtensionDecl>(value->getDeclContext())) {
1894+
if (auto isolationFromAttr = getIsolationFromAttributes(ext)) {
1895+
return inferredIsolation(*isolationFromAttr);
1896+
}
18941897
}
1895-
}
18961898

1897-
// If the declaration is in a nominal type (or extension thereof) that
1898-
// has isolation, use that.
1899-
if (auto selfTypeDecl = value->getDeclContext()->getSelfNominalTypeDecl()) {
1900-
auto selfTypeIsolation = getActorIsolation(selfTypeDecl);
1901-
if (!selfTypeIsolation.isUnspecified()) {
1902-
return inferredIsolation(selfTypeIsolation);
1899+
// If the declaration is in a nominal type (or extension thereof) that
1900+
// has isolation, use that.
1901+
if (auto selfTypeDecl = value->getDeclContext()->getSelfNominalTypeDecl()) {
1902+
auto selfTypeIsolation = getActorIsolation(selfTypeDecl);
1903+
if (!selfTypeIsolation.isUnspecified()) {
1904+
return inferredIsolation(selfTypeIsolation);
1905+
}
19031906
}
19041907
}
19051908

test/Concurrency/actor_isolation.swift

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -406,4 +406,20 @@ actor class LazyActor {
406406
@actorIndependent lazy var l43: Int = { self.l }()
407407
@actorIndependent lazy var l44: Int = self.l
408408
@actorIndependent lazy var l45: Int = { [unowned self] in self.l }()
409-
}
409+
}
410+
411+
// Infer global actors from context only for instance members.
412+
@MainActor
413+
class SomeClassInActor {
414+
enum ID: String { case best }
415+
416+
func inActor() { } // expected-note{{calls to instance method 'inActor()' from outside of its actor context are implicitly asynchronous}}
417+
}
418+
419+
extension SomeClassInActor.ID {
420+
func f(_ object: SomeClassInActor) { // expected-note{{add '@MainActor' to make instance method 'f' part of global actor 'MainActor'}}
421+
// expected-note@-1{{add 'async' to function 'f' to make it asynchronous}}
422+
// expected-note@-2{{add '@asyncHandler' to function 'f' to create an implicit asynchronous context}}
423+
object.inActor() // expected-error{{'async' in a function that does not support concurrency}}
424+
}
425+
}

test/decl/class/circular_inheritance.swift

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@
44
// RUN: not %target-swift-frontend -typecheck -debug-cycles %s -build-request-dependency-graph -output-request-graphviz %t.dot -stats-output-dir %t/stats-dir 2> %t.cycles
55
// RUN: %FileCheck -check-prefix CHECK-DOT %s < %t.dot
66

7-
class Left // expected-error {{'Left' inherits from itself}} expected-note 2{{through reference here}}
7+
class Left // expected-error {{'Left' inherits from itself}} expected-note {{through reference here}}
88
: Right.Hand { // expected-note {{through reference here}}
9-
class Hand {} // expected-note {{through reference here}}
9+
class Hand {}
1010
}
1111

12-
class Right // expected-note 2 {{through reference here}} expected-note{{class 'Right' declared here}}
12+
class Right // expected-note {{through reference here}} expected-note{{class 'Right' declared here}}
1313
: Left.Hand { // expected-note {{through reference here}}
14-
class Hand {} // expected-error {{circular reference}}
14+
class Hand {}
1515
}
1616

1717
class C : B { } // expected-error{{'C' inherits from itself}}
@@ -30,15 +30,15 @@ class Outer {
3030
class Inner : Outer {}
3131
}
3232

33-
class Outer2 // expected-error {{'Outer2' inherits from itself}} expected-note 2 {{through reference here}}
33+
class Outer2 // expected-error {{'Outer2' inherits from itself}} expected-note {{through reference here}}
3434
: Outer2.Inner { // expected-note {{through reference here}}
3535

36-
class Inner {} // expected-error{{circular reference}}
36+
class Inner {}
3737
}
3838

39-
class Outer3 // expected-error {{'Outer3' inherits from itself}} expected-note 2 {{through reference here}}
39+
class Outer3 // expected-error {{'Outer3' inherits from itself}} expected-note {{through reference here}}
4040
: Outer3.Inner<Int> { // expected-note {{through reference here}}
41-
class Inner<T> {} // expected-error{{circular reference}}
41+
class Inner<T> {}
4242
}
4343

4444
// CHECK-DOT: digraph Dependencies

0 commit comments

Comments
 (0)