Skip to content

Commit 0312054

Browse files
committed
[Concurrency] Handle implicitly async operator expressions in the actor
isolation checker. Previously, the actor isolation checker would crash when attempting to mark an operator call as implicitly async, because it was specifically expecting to see a CallExpr. Instead, accept all ApplyExprs except for SelfApplyExpr.
1 parent fb259ea commit 0312054

File tree

2 files changed

+40
-15
lines changed

2 files changed

+40
-15
lines changed

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2887,22 +2887,27 @@ namespace {
28872887
assert(applyStack.size() > 0 && "not contained within an Apply?");
28882888

28892889
const auto End = applyStack.rend();
2890-
for (auto I = applyStack.rbegin(); I != End; ++I)
2891-
if (auto call = dyn_cast<CallExpr>(I->dyn_cast<ApplyExpr *>())) {
2892-
if (setAsync) {
2893-
call->setImplicitlyAsync(*setAsync);
2894-
}
2895-
if (setThrows) {
2896-
call->setImplicitlyThrows(true);
2897-
}else {
2898-
call->setImplicitlyThrows(false);
2899-
}
2900-
if (setDistributedThunk) {
2901-
call->setShouldApplyDistributedThunk(true);
2902-
}
2903-
return;
2890+
for (auto I = applyStack.rbegin(); I != End; ++I) {
2891+
auto *apply = I->dyn_cast<ApplyExpr *>();
2892+
if (!apply || isa<SelfApplyExpr>(apply)) {
2893+
continue;
2894+
}
2895+
2896+
if (setAsync) {
2897+
apply->setImplicitlyAsync(*setAsync);
29042898
}
2905-
llvm_unreachable("expected a CallExpr in applyStack!");
2899+
if (setThrows) {
2900+
apply->setImplicitlyThrows(true);
2901+
} else {
2902+
apply->setImplicitlyThrows(false);
2903+
}
2904+
if (setDistributedThunk) {
2905+
apply->setShouldApplyDistributedThunk(true);
2906+
}
2907+
return;
2908+
}
2909+
2910+
llvm_unreachable("expected an ApplyExpr in applyStack!");
29062911
}
29072912

29082913
MacroWalking getMacroWalkingBehavior() const override {

test/Concurrency/actor_call_implicitly_async.swift

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -576,3 +576,23 @@ func tryTheActorSubscripts(a : SubscriptA, t : SubscriptT, at : SubscriptAT) asy
576576

577577
_ = try await at[0]
578578
}
579+
580+
@MainActor
581+
final class IsolatedOperator: @preconcurrency Equatable {
582+
static func == (lhs: IsolatedOperator, rhs: IsolatedOperator) -> Bool {
583+
lhs.num == rhs.num
584+
}
585+
586+
var num = 0
587+
588+
init(num: Int = 0) {
589+
self.num = num
590+
}
591+
592+
nonisolated func callEqual() async -> Bool {
593+
let foo = await IsolatedOperator()
594+
// expected-error@+2{{expression is 'async' but is not marked with 'await'}}
595+
// expected-note@+1{{calls to operator function '==' from outside of its actor context are implicitly asynchronous}}
596+
return foo == self
597+
}
598+
}

0 commit comments

Comments
 (0)