Skip to content

Commit fc42640

Browse files
committed
[Concurrency] Prohibit partial application of actor-isolated methods.
1 parent 2649749 commit fc42640

File tree

4 files changed

+33
-3
lines changed

4 files changed

+33
-3
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4149,6 +4149,9 @@ ERROR(actor_isolated_self_independent_context,none,
41494149
"actor-isolated %0 %1 can not be referenced from an "
41504150
"'@actorIndependent' context",
41514151
(DescriptiveDeclKind, DeclName))
4152+
ERROR(actor_isolated_partial_apply,none,
4153+
"actor-isolated %0 %1 can not be partially applied",
4154+
(DescriptiveDeclKind, DeclName))
41524155
WARNING(concurrent_access_local,none,
41534156
"local %0 %1 is unsafe to reference in code that may execute "
41544157
"concurrently",

lib/Sema/CSApply.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -925,7 +925,6 @@ namespace {
925925

926926
case ValueOwnership::Owned:
927927
case ValueOwnership::Shared:
928-
// Ensure that the argument type matches up exactly.
929928
auto selfArgTy = ParenType::get(context,
930929
selfParam.getPlainType(),
931930
selfParam.getParameterFlags());

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -566,6 +566,25 @@ void swift::checkActorIsolation(const Expr *expr, const DeclContext *dc) {
566566
return false;
567567

568568
case IsolationRestriction::ActorSelf: {
569+
// Cannot refer to actor-isolated state in a partial application.
570+
if (auto autoclosure = dyn_cast<AutoClosureExpr>(getDeclContext())) {
571+
switch (autoclosure->getThunkKind()) {
572+
case AutoClosureExpr::Kind::DoubleCurryThunk:
573+
case AutoClosureExpr::Kind::SingleCurryThunk:
574+
ctx.Diags.diagnose(
575+
memberLoc, diag::actor_isolated_partial_apply,
576+
member->getDescriptiveKind(),
577+
member->getName());
578+
noteIsolatedActorMember(member);
579+
return true;
580+
581+
case AutoClosureExpr::Kind::None:
582+
// Not in a partial application.
583+
break;
584+
}
585+
}
586+
587+
// Must reference actor-isolated state on 'self'.
569588
auto selfVar = getSelfReference(base);
570589
if (!selfVar) {
571590
ctx.Diags.diagnose(

test/Concurrency/actor_isolation.swift

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ func acceptEscapingClosure<T>(_: @escaping () -> T) { }
1313
actor class MySuperActor {
1414
var superState: Int = 25
1515

16-
func superMethod() { }
16+
func superMethod() { } // expected-note 2 {{only asynchronous methods can be used outside the actor instance; do you want to add 'async'?}}
1717
func superAsyncMethod() async { }
1818

1919
subscript (index: Int) -> String { // expected-note{{subscript declared here}}
@@ -28,7 +28,7 @@ actor class MyActor: MySuperActor {
2828
class func synchronousClass() { }
2929
static func synchronousStatic() { }
3030

31-
func synchronous() -> String { text.first ?? "nothing" } // expected-note 6{{only asynchronous methods can be used outside the actor instance; do you want to add 'async'?}}
31+
func synchronous() -> String { text.first ?? "nothing" } // expected-note 8{{only asynchronous methods can be used outside the actor instance; do you want to add 'async'?}}
3232
func asynchronous() async -> String { synchronous() }
3333
}
3434

@@ -46,6 +46,7 @@ extension MyActor {
4646
// @actorIndependent
4747
_ = actorIndependentFunc(otherActor: self)
4848
_ = actorIndependentVar
49+
4950
actorIndependentVar = 17
5051
_ = self.actorIndependentFunc(otherActor: self)
5152
_ = self.actorIndependentVar
@@ -60,6 +61,10 @@ extension MyActor {
6061
_ = immutableGlobal
6162
_ = mutableGlobal // expected-warning{{reference to var 'mutableGlobal' is not concurrency-safe because it involves shared mutable state}}
6263

64+
// Partial application
65+
_ = synchronous // expected-error{{actor-isolated instance method 'synchronous()' can not be partially applied}}
66+
_ = super.superMethod // expected-error{{actor-isolated instance method 'superMethod()' can not be partially applied}}
67+
6368
return 5
6469
}
6570

@@ -137,6 +142,10 @@ extension MyActor {
137142
}
138143

139144
localVar = 0
145+
146+
// Partial application
147+
_ = synchronous // expected-error{{actor-isolated instance method 'synchronous()' can not be partially applied}}
148+
_ = super.superMethod // expected-error{{actor-isolated instance method 'superMethod()' can not be partially applied}}
140149
}
141150
}
142151

0 commit comments

Comments
 (0)