Skip to content

Commit 8387075

Browse files
committed
[Concurrency] Only infer extension/nominal actor for instance members.
Fixes rdar://72966018.
1 parent d0564c0 commit 8387075

File tree

2 files changed

+32
-13
lines changed

2 files changed

+32
-13
lines changed

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
}

0 commit comments

Comments
 (0)