Skip to content

Commit 17b2203

Browse files
committed
some vars need unspecified isolation for initializing exprs
It's possible to create an impossible set of constraints for instance-member stored properties of a type. For example: @mainactor func getStatus() -> Int { /* ... */ } @PIDActor func genPID() -> ProcessID { /* ... */ } class Process { @mainactor var status: Int = getStatus() @PIDActor var pid: ProcessID = genPID() init() {} // Problem: what is the isolation of this init? } We cannot satisfy the isolation of the initilizing expressions, which demand that genStatus and genPID are run with isolation from a non-async designated initializer, which is not possible. This patch changes the isolation for those initializer expressions for instance members, saying that the isolation is unspecified. fixes rdar://84225474
1 parent d131c37 commit 17b2203

File tree

2 files changed

+33
-2
lines changed

2 files changed

+33
-2
lines changed

lib/AST/Decl.cpp

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8662,10 +8662,23 @@ ActorIsolation swift::getActorIsolationOfContext(DeclContext *dc) {
86628662
if (auto *vd = dyn_cast_or_null<ValueDecl>(dc->getAsDecl()))
86638663
return getActorIsolation(vd);
86648664

8665+
// In the context of the initializing or default-value expression of a
8666+
// stored property, the isolation varies between global and type members:
8667+
// - For a static stored property, the isolation matches the VarDecl.
8668+
// - For a field of a nominal type, the expression is not isolated.
8669+
// Without this distinction, a nominal can have non-async initializers
8670+
// with various kinds of isolation, so an impossible constraint can be
8671+
// created. See SE-0327 for details.
86658672
if (auto *init = dyn_cast<PatternBindingInitializer>(dc)) {
8666-
if (auto *var = init->getBinding()->getAnchoringVarDecl(
8667-
init->getBindingIndex()))
8673+
if (auto *var =
8674+
init->getBinding()->getAnchoringVarDecl(init->getBindingIndex())) {
8675+
8676+
if (var->isInstanceMember() &&
8677+
!var->getAttrs().hasAttribute<LazyAttr>())
8678+
return ActorIsolation::forUnspecified();
8679+
86688680
return getActorIsolation(var);
8681+
}
86698682
}
86708683

86718684
if (auto *closure = dyn_cast<AbstractClosureExpr>(dc)) {
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// RUN: %target-typecheck-verify-swift -disable-availability-checking -warn-concurrency
2+
// REQUIRES: concurrency
3+
4+
5+
@MainActor
6+
func mainActorFn() -> Int { return 0 } // expected-note 2 {{calls to global function 'mainActorFn()' from outside of its actor context are implicitly asynchronous}}
7+
8+
@MainActor
9+
class C {
10+
var x: Int = mainActorFn() // expected-error {{call to main actor-isolated global function 'mainActorFn()' in a synchronous nonisolated context}}
11+
12+
lazy var y: Int = mainActorFn()
13+
14+
static var z: Int = mainActorFn()
15+
}
16+
17+
@MainActor
18+
var x: Int = mainActorFn() // expected-error {{call to main actor-isolated global function 'mainActorFn()' in a synchronous nonisolated context}}

0 commit comments

Comments
 (0)