Skip to content

Commit 52f3fb2

Browse files
xedinktoso
authored andcommitted
[TypeChecker] Concurrency: turn checkDistributedAccess into validity check
All the heavy lifting of checking whether reference throws and requires dispatch through a thunk is done during type-checking, so all `checkDistributedAccess` needs to do is determine whether access is distributed or not.
1 parent 42ad169 commit 52f3fb2

File tree

1 file changed

+17
-53
lines changed

1 file changed

+17
-53
lines changed

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 17 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1721,9 +1721,7 @@ namespace {
17211721
///
17221722
/// and we reach up to mark the CallExpr.
17231723
void markNearestCallAsImplicitly(
1724-
Optional<ImplicitActorHopTarget> setAsync,
1725-
bool setThrows = false,
1726-
bool setDistributedThunk = false) {
1724+
Optional<ImplicitActorHopTarget> setAsync) {
17271725
assert(applyStack.size() > 0 && "not contained within an Apply?");
17281726

17291727
const auto End = applyStack.rend();
@@ -1732,14 +1730,6 @@ namespace {
17321730
if (setAsync) {
17331731
call->setImplicitlyAsync(*setAsync);
17341732
}
1735-
if (setThrows) {
1736-
call->setImplicitlyThrows(true);
1737-
}else {
1738-
call->setImplicitlyThrows(false);
1739-
}
1740-
if (setDistributedThunk) {
1741-
call->setUsesDistributedThunk(true);
1742-
}
17431733
return;
17441734
}
17451735
llvm_unreachable("expected a CallExpr in applyStack!");
@@ -2240,42 +2230,30 @@ namespace {
22402230
/// isolated to a distributed actor from a location that is potentially not
22412231
/// local to this process.
22422232
///
2243-
/// \returns the (setThrows, isDistributedThunk) bits to implicitly
2244-
/// mark the access/call with on success, or emits an error and returns
2245-
/// \c None.
2246-
Optional<std::pair<bool, bool>>
2247-
checkDistributedAccess(SourceLoc declLoc, ValueDecl *decl,
2248-
Expr *context) {
2233+
/// \returns true if the access is from outside of actors isolation
2234+
/// context and false otherwise.
2235+
bool isDistributedAccess(SourceLoc declLoc, ValueDecl *decl,
2236+
Expr *context) {
22492237
// If base of the call is 'local' we permit skip distributed checks.
22502238
if (auto baseSelf = findReferencedBaseSelf(context)) {
2251-
if (baseSelf->getAttrs().hasAttribute<KnownToBeLocalAttr>()) {
2252-
return std::make_pair(
2253-
/*setThrows=*/false,
2254-
/*isDistributedThunk=*/false);
2255-
}
2239+
if (baseSelf->getAttrs().hasAttribute<KnownToBeLocalAttr>())
2240+
return false;
22562241
}
22572242

22582243
// Cannot reference subscripts, or stored properties.
22592244
auto var = dyn_cast<VarDecl>(decl);
22602245
if (isa<SubscriptDecl>(decl) || var) {
22612246
// But computed distributed properties are okay,
22622247
// and treated the same as a distributed func.
2263-
if (var && var->isDistributed()) {
2264-
bool explicitlyThrowing = false;
2265-
if (auto getter = var->getAccessor(swift::AccessorKind::Get)) {
2266-
explicitlyThrowing = getter->hasThrows();
2267-
}
2268-
return std::make_pair(
2269-
/*setThrows*/!explicitlyThrowing,
2270-
/*isDistributedThunk=*/true);
2271-
}
2248+
if (var && var->isDistributed())
2249+
return true;
22722250

22732251
// otherwise, it was a normal property or subscript and therefore illegal
22742252
ctx.Diags.diagnose(
22752253
declLoc, diag::distributed_actor_isolated_non_self_reference,
22762254
decl->getDescriptiveKind(), decl->getName());
22772255
noteIsolatedActorMember(decl, context);
2278-
return None;
2256+
return false;
22792257
}
22802258

22812259
// Check that we have a distributed function or computed property.
@@ -2286,15 +2264,13 @@ namespace {
22862264
.fixItInsert(decl->getAttributeInsertionLoc(true), "distributed ");
22872265

22882266
noteIsolatedActorMember(decl, context);
2289-
return None;
2267+
return false;
22902268
}
22912269

2292-
return std::make_pair(
2293-
/*setThrows=*/!afd->hasThrows(),
2294-
/*isDistributedThunk=*/true);
2270+
return true;
22952271
}
22962272

2297-
return std::make_pair(/*setThrows=*/false, /*distributedThunk=*/false);
2273+
return false;
22982274
}
22992275

23002276
/// Attempts to identify and mark a valid cross-actor use of a synchronous
@@ -2312,13 +2288,8 @@ namespace {
23122288
if (isPropOrSubscript(decl)) {
23132289
// Cannot reference properties or subscripts of distributed actors.
23142290
if (isDistributed) {
2315-
bool setThrows = false;
2316-
bool usesDistributedThunk = false;
2317-
if (auto access = checkDistributedAccess(declLoc, decl, context)) {
2318-
std::tie(setThrows, usesDistributedThunk) = *access;
2319-
} else {
2291+
if (!isDistributedAccess(declLoc, decl, context))
23202292
return AsyncMarkingResult::NotDistributed;
2321-
}
23222293
}
23232294

23242295
if (auto declRef = dyn_cast_or_null<DeclRefExpr>(context)) {
@@ -2374,20 +2345,13 @@ namespace {
23742345
if (isAsyncCall) {
23752346
// If we're calling to a distributed actor, make sure the function
23762347
// is actually 'distributed'.
2377-
bool setThrows = false;
2378-
bool usesDistributedThunk = false;
23792348
if (isDistributed) {
2380-
if (auto access = checkDistributedAccess(declLoc, decl, context)) {
2381-
std::tie(setThrows, usesDistributedThunk) = *access;
2382-
} else {
2349+
if (!isDistributedAccess(declLoc, decl, context))
23832350
return AsyncMarkingResult::NotDistributed;
2384-
}
23852351
}
23862352

2387-
// Mark call as implicitly 'async', and also potentially as
2388-
// throwing and using a distributed thunk.
2389-
markNearestCallAsImplicitly(
2390-
/*setAsync=*/target, setThrows, usesDistributedThunk);
2353+
// Mark call as implicitly 'async'.
2354+
markNearestCallAsImplicitly(/*setAsync=*/target);
23912355
result = AsyncMarkingResult::FoundAsync;
23922356
}
23932357

0 commit comments

Comments
 (0)