Skip to content

Commit b45f39a

Browse files
committed
[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 add6713 commit b45f39a

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
@@ -1762,9 +1762,7 @@ namespace {
17621762
///
17631763
/// and we reach up to mark the CallExpr.
17641764
void markNearestCallAsImplicitly(
1765-
Optional<ImplicitActorHopTarget> setAsync,
1766-
bool setThrows = false,
1767-
bool setDistributedThunk = false) {
1765+
Optional<ImplicitActorHopTarget> setAsync) {
17681766
assert(applyStack.size() > 0 && "not contained within an Apply?");
17691767

17701768
const auto End = applyStack.rend();
@@ -1773,14 +1771,6 @@ namespace {
17731771
if (setAsync) {
17741772
call->setImplicitlyAsync(*setAsync);
17751773
}
1776-
if (setThrows) {
1777-
call->setImplicitlyThrows(true);
1778-
}else {
1779-
call->setImplicitlyThrows(false);
1780-
}
1781-
if (setDistributedThunk) {
1782-
call->setUsesDistributedThunk(true);
1783-
}
17841774
return;
17851775
}
17861776
llvm_unreachable("expected a CallExpr in applyStack!");
@@ -2290,42 +2280,30 @@ namespace {
22902280
/// isolated to a distributed actor from a location that is potentially not
22912281
/// local to this process.
22922282
///
2293-
/// \returns the (setThrows, isDistributedThunk) bits to implicitly
2294-
/// mark the access/call with on success, or emits an error and returns
2295-
/// \c None.
2296-
Optional<std::pair<bool, bool>>
2297-
checkDistributedAccess(SourceLoc declLoc, ValueDecl *decl,
2298-
Expr *context) {
2283+
/// \returns true if the access is from outside of actors isolation
2284+
/// context and false otherwise.
2285+
bool isDistributedAccess(SourceLoc declLoc, ValueDecl *decl,
2286+
Expr *context) {
22992287
// If base of the call is 'local' we permit skip distributed checks.
23002288
if (auto baseSelf = findReferencedBaseSelf(context)) {
2301-
if (baseSelf->getAttrs().hasAttribute<KnownToBeLocalAttr>()) {
2302-
return std::make_pair(
2303-
/*setThrows=*/false,
2304-
/*isDistributedThunk=*/false);
2305-
}
2289+
if (baseSelf->getAttrs().hasAttribute<KnownToBeLocalAttr>())
2290+
return false;
23062291
}
23072292

23082293
// Cannot reference subscripts, or stored properties.
23092294
auto var = dyn_cast<VarDecl>(decl);
23102295
if (isa<SubscriptDecl>(decl) || var) {
23112296
// But computed distributed properties are okay,
23122297
// and treated the same as a distributed func.
2313-
if (var && var->isDistributed()) {
2314-
bool explicitlyThrowing = false;
2315-
if (auto getter = var->getAccessor(swift::AccessorKind::Get)) {
2316-
explicitlyThrowing = getter->hasThrows();
2317-
}
2318-
return std::make_pair(
2319-
/*setThrows*/!explicitlyThrowing,
2320-
/*isDistributedThunk=*/true);
2321-
}
2298+
if (var && var->isDistributed())
2299+
return true;
23222300

23232301
// otherwise, it was a normal property or subscript and therefore illegal
23242302
ctx.Diags.diagnose(
23252303
declLoc, diag::distributed_actor_isolated_non_self_reference,
23262304
decl->getDescriptiveKind(), decl->getName());
23272305
noteIsolatedActorMember(decl, context);
2328-
return None;
2306+
return false;
23292307
}
23302308

23312309
// Check that we have a distributed function or computed property.
@@ -2336,15 +2314,13 @@ namespace {
23362314
.fixItInsert(decl->getAttributeInsertionLoc(true), "distributed ");
23372315

23382316
noteIsolatedActorMember(decl, context);
2339-
return None;
2317+
return false;
23402318
}
23412319

2342-
return std::make_pair(
2343-
/*setThrows=*/!afd->hasThrows(),
2344-
/*isDistributedThunk=*/true);
2320+
return true;
23452321
}
23462322

2347-
return std::make_pair(/*setThrows=*/false, /*distributedThunk=*/false);
2323+
return false;
23482324
}
23492325

23502326
/// Attempts to identify and mark a valid cross-actor use of a synchronous
@@ -2362,13 +2338,8 @@ namespace {
23622338
if (isPropOrSubscript(decl)) {
23632339
// Cannot reference properties or subscripts of distributed actors.
23642340
if (isDistributed) {
2365-
bool setThrows = false;
2366-
bool usesDistributedThunk = false;
2367-
if (auto access = checkDistributedAccess(declLoc, decl, context)) {
2368-
std::tie(setThrows, usesDistributedThunk) = *access;
2369-
} else {
2341+
if (!isDistributedAccess(declLoc, decl, context))
23702342
return AsyncMarkingResult::NotDistributed;
2371-
}
23722343
}
23732344

23742345
if (auto declRef = dyn_cast_or_null<DeclRefExpr>(context)) {
@@ -2424,20 +2395,13 @@ namespace {
24242395
if (isAsyncCall) {
24252396
// If we're calling to a distributed actor, make sure the function
24262397
// is actually 'distributed'.
2427-
bool setThrows = false;
2428-
bool usesDistributedThunk = false;
24292398
if (isDistributed) {
2430-
if (auto access = checkDistributedAccess(declLoc, decl, context)) {
2431-
std::tie(setThrows, usesDistributedThunk) = *access;
2432-
} else {
2399+
if (!isDistributedAccess(declLoc, decl, context))
24332400
return AsyncMarkingResult::NotDistributed;
2434-
}
24352401
}
24362402

2437-
// Mark call as implicitly 'async', and also potentially as
2438-
// throwing and using a distributed thunk.
2439-
markNearestCallAsImplicitly(
2440-
/*setAsync=*/target, setThrows, usesDistributedThunk);
2403+
// Mark call as implicitly 'async'.
2404+
markNearestCallAsImplicitly(/*setAsync=*/target);
24412405
result = AsyncMarkingResult::FoundAsync;
24422406
}
24432407

0 commit comments

Comments
 (0)