Skip to content

Commit 386940c

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 669e3f3 commit 386940c

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
@@ -8682,10 +8682,23 @@ ActorIsolation swift::getActorIsolationOfContext(DeclContext *dc) {
86828682
if (auto *vd = dyn_cast_or_null<ValueDecl>(dc->getAsDecl()))
86838683
return getActorIsolation(vd);
86848684

8685+
// In the context of the initializing or default-value expression of a
8686+
// stored property, the isolation varies between global and type members:
8687+
// - For a static stored property, the isolation matches the VarDecl.
8688+
// - For a field of a nominal type, the expression is not isolated.
8689+
// Without this distinction, a nominal can have non-async initializers
8690+
// with various kinds of isolation, so an impossible constraint can be
8691+
// created. See SE-0327 for details.
86858692
if (auto *init = dyn_cast<PatternBindingInitializer>(dc)) {
8686-
if (auto *var = init->getBinding()->getAnchoringVarDecl(
8687-
init->getBindingIndex()))
8693+
if (auto *var =
8694+
init->getBinding()->getAnchoringVarDecl(init->getBindingIndex())) {
8695+
8696+
if (var->isInstanceMember() &&
8697+
!var->getAttrs().hasAttribute<LazyAttr>())
8698+
return ActorIsolation::forUnspecified();
8699+
86888700
return getActorIsolation(var);
8701+
}
86898702
}
86908703

86918704
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)