Skip to content

Commit d34063b

Browse files
committed
Simplify 'inout' check for isolated actor state in async calls.
(cherry picked from commit 32c1832)
1 parent c8ffc30 commit d34063b

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
@@ -1315,6 +1315,9 @@ ReferencedActor ReferencedActor::forGlobalActor(VarDecl *actor,
13151315
return ReferencedActor(actor, isPotentiallyIsolated, kind, globalActor);
13161316
}
13171317

1318+
static ActorIsolation getActorIsolationForReference(
1319+
ValueDecl *decl, const DeclContext *fromDC);
1320+
13181321
bool ReferencedActor::isKnownToBeLocal() const {
13191322
switch (kind) {
13201323
case GlobalActor:
@@ -2311,54 +2314,36 @@ namespace {
23112314
return false;
23122315

23132316
bool result = false;
2314-
auto checkDiagnostic = [this, call, isPartialApply,
2315-
&result](ValueDecl *decl, SourceLoc argLoc) {
2316-
auto isolation = ActorIsolationRestriction::forDeclaration(
2317-
decl, getDeclContext());
2318-
switch (isolation) {
2319-
case ActorIsolationRestriction::Unrestricted:
2320-
case ActorIsolationRestriction::Unsafe:
2321-
break;
2322-
case ActorIsolationRestriction::GlobalActorUnsafe:
2323-
// If we're not supposed to diagnose existing data races here,
2324-
// we're done.
2325-
if (!shouldDiagnoseExistingDataRaces(getDeclContext()))
2326-
break;
2327-
2328-
LLVM_FALLTHROUGH;
2317+
auto checkDiagnostic = [this, call, isPartialApply, &result](
2318+
ConcreteDeclRef declRef, SourceLoc argLoc) {
2319+
auto decl = declRef.getDecl();
2320+
auto isolation = getActorIsolationForReference(decl, getDeclContext());
2321+
if (!isolation.isActorIsolated())
2322+
return;
23292323

2330-
case ActorIsolationRestriction::GlobalActor: {
2331-
ctx.Diags.diagnose(argLoc, diag::actor_isolated_inout_state,
2332-
decl->getDescriptiveKind(), decl->getName(),
2333-
call->isImplicitlyAsync().hasValue());
2334-
decl->diagnose(diag::kind_declared_here, decl->getDescriptiveKind());
2335-
result = true;
2336-
break;
2337-
}
2338-
case ActorIsolationRestriction::CrossActorSelf:
2339-
case ActorIsolationRestriction::ActorSelf: {
2340-
if (isPartialApply) {
2341-
// The partially applied InoutArg is a property of actor. This
2342-
// can really only happen when the property is a struct with a
2343-
// mutating async method.
2344-
if (auto partialApply = dyn_cast<ApplyExpr>(call->getFn())) {
2345-
ValueDecl *fnDecl =
2346-
cast<DeclRefExpr>(partialApply->getFn())->getDecl();
2324+
if (isPartialApply) {
2325+
// The partially applied InoutArg is a property of actor. This
2326+
// can really only happen when the property is a struct with a
2327+
// mutating async method.
2328+
if (auto partialApply = dyn_cast<ApplyExpr>(call->getFn())) {
2329+
if (auto declRef = dyn_cast<DeclRefExpr>(partialApply->getFn())) {
2330+
ValueDecl *fnDecl = declRef->getDecl();
23472331
ctx.Diags.diagnose(call->getLoc(),
23482332
diag::actor_isolated_mutating_func,
23492333
fnDecl->getName(), decl->getDescriptiveKind(),
23502334
decl->getName());
23512335
result = true;
2336+
return;
23522337
}
2353-
} else {
2354-
ctx.Diags.diagnose(argLoc, diag::actor_isolated_inout_state,
2355-
decl->getDescriptiveKind(), decl->getName(),
2356-
call->isImplicitlyAsync().hasValue());
2357-
result = true;
23582338
}
2359-
break;
2360-
}
23612339
}
2340+
2341+
ctx.Diags.diagnose(argLoc, diag::actor_isolated_inout_state,
2342+
decl->getDescriptiveKind(), decl->getName(),
2343+
call->isImplicitlyAsync().hasValue());
2344+
decl->diagnose(diag::kind_declared_here, decl->getDescriptiveKind());
2345+
result = true;
2346+
return;
23622347
};
23632348
auto expressionWalker = [baseArg = arg->getSubExpr(),
23642349
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)