Skip to content

Commit 32c1832

Browse files
committed
Simplify 'inout' check for isolated actor state in async calls.
1 parent 1b27c48 commit 32c1832

File tree

2 files changed

+34
-49
lines changed

2 files changed

+34
-49
lines changed

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 24 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1261,6 +1261,9 @@ ReferencedActor ReferencedActor::forGlobalActor(VarDecl *actor,
12611261
return ReferencedActor(actor, isPotentiallyIsolated, kind, globalActor);
12621262
}
12631263

1264+
static ActorIsolation getActorIsolationForReference(
1265+
ValueDecl *decl, const DeclContext *fromDC);
1266+
12641267
bool ReferencedActor::isKnownToBeLocal() const {
12651268
switch (kind) {
12661269
case GlobalActor:
@@ -2250,54 +2253,36 @@ namespace {
22502253
return false;
22512254

22522255
bool result = false;
2253-
auto checkDiagnostic = [this, call, isPartialApply,
2254-
&result](ValueDecl *decl, SourceLoc argLoc) {
2255-
auto isolation = ActorIsolationRestriction::forDeclaration(
2256-
decl, getDeclContext());
2257-
switch (isolation) {
2258-
case ActorIsolationRestriction::Unrestricted:
2259-
case ActorIsolationRestriction::Unsafe:
2260-
break;
2261-
case ActorIsolationRestriction::GlobalActorUnsafe:
2262-
// If we're not supposed to diagnose existing data races here,
2263-
// we're done.
2264-
if (!shouldDiagnoseExistingDataRaces(getDeclContext()))
2265-
break;
2266-
2267-
LLVM_FALLTHROUGH;
2256+
auto checkDiagnostic = [this, call, isPartialApply, &result](
2257+
ConcreteDeclRef declRef, SourceLoc argLoc) {
2258+
auto decl = declRef.getDecl();
2259+
auto isolation = getActorIsolationForReference(decl, getDeclContext());
2260+
if (!isolation.isActorIsolated())
2261+
return;
22682262

2269-
case ActorIsolationRestriction::GlobalActor: {
2270-
ctx.Diags.diagnose(argLoc, diag::actor_isolated_inout_state,
2271-
decl->getDescriptiveKind(), decl->getName(),
2272-
call->isImplicitlyAsync().hasValue());
2273-
decl->diagnose(diag::kind_declared_here, decl->getDescriptiveKind());
2274-
result = true;
2275-
break;
2276-
}
2277-
case ActorIsolationRestriction::CrossActorSelf:
2278-
case ActorIsolationRestriction::ActorSelf: {
2279-
if (isPartialApply) {
2280-
// The partially applied InoutArg is a property of actor. This
2281-
// can really only happen when the property is a struct with a
2282-
// mutating async method.
2283-
if (auto partialApply = dyn_cast<ApplyExpr>(call->getFn())) {
2284-
ValueDecl *fnDecl =
2285-
cast<DeclRefExpr>(partialApply->getFn())->getDecl();
2263+
if (isPartialApply) {
2264+
// The partially applied InoutArg is a property of actor. This
2265+
// can really only happen when the property is a struct with a
2266+
// mutating async method.
2267+
if (auto partialApply = dyn_cast<ApplyExpr>(call->getFn())) {
2268+
if (auto declRef = dyn_cast<DeclRefExpr>(partialApply->getFn())) {
2269+
ValueDecl *fnDecl = declRef->getDecl();
22862270
ctx.Diags.diagnose(call->getLoc(),
22872271
diag::actor_isolated_mutating_func,
22882272
fnDecl->getName(), decl->getDescriptiveKind(),
22892273
decl->getName());
22902274
result = true;
2275+
return;
22912276
}
2292-
} else {
2293-
ctx.Diags.diagnose(argLoc, diag::actor_isolated_inout_state,
2294-
decl->getDescriptiveKind(), decl->getName(),
2295-
call->isImplicitlyAsync().hasValue());
2296-
result = true;
22972277
}
2298-
break;
2299-
}
23002278
}
2279+
2280+
ctx.Diags.diagnose(argLoc, diag::actor_isolated_inout_state,
2281+
decl->getDescriptiveKind(), decl->getName(),
2282+
call->isImplicitlyAsync().hasValue());
2283+
decl->diagnose(diag::kind_declared_here, decl->getDescriptiveKind());
2284+
result = true;
2285+
return;
23012286
};
23022287
auto expressionWalker = [baseArg = arg->getSubExpr(),
23032288
checkDiagnostic](Expr *expr) -> Expr * {

test/Concurrency/actor_inout_isolation.swift

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,11 @@ struct Point {
2525
@available(SwiftStdlib 5.1, *)
2626
actor TestActor {
2727
// expected-note@+1{{mutation of this property is only permitted within the actor}}
28-
var position = Point(x: 0, y: 0)
29-
var nextPosition = Point(x: 0, y: 1)
30-
var value1: Int = 0
31-
var value2: Int = 1
32-
var points: [Point] = []
28+
var position = Point(x: 0, y: 0) // expected-note 2{{property declared here}}
29+
var nextPosition = Point(x: 0, y: 1) // expected-note 2{{property declared here}}
30+
var value1: Int = 0 // expected-note 6{{property declared here}}
31+
var value2: Int = 1 // expected-note 4{{property declared here}}
32+
var points: [Point] = [] // expected-note {{property declared here}}
3333

3434
subscript(x : inout Int) -> Int { // expected-error {{'inout' must not be used on subscript parameters}}
3535
x += 1
@@ -162,11 +162,11 @@ extension TestActor {
162162

163163
@available(SwiftStdlib 5.1, *)
164164
actor MyActor {
165-
var points: [Point] = []
166-
var int: Int = 0
167-
var maybeInt: Int?
168-
var maybePoint: Point?
169-
var myActor: TestActor = TestActor()
165+
var points: [Point] = [] // expected-note 2{{property declared here}}
166+
var int: Int = 0 // expected-note 2{{property declared here}}
167+
var maybeInt: Int? // expected-note 1{{property declared here}}
168+
var maybePoint: Point? // expected-note 1{{property declared here}}
169+
var myActor: TestActor = TestActor() // expected-note 1{{property declared here}}
170170

171171
// Checking that various ways of unwrapping emit the right error messages at
172172
// the right times and that illegal operations are caught

0 commit comments

Comments
 (0)