Skip to content

Commit 3558237

Browse files
committed
Partial actor isolation checking for #isolation
This isn't done very well, and is expected to be replaced, but it allows us to avoid bogus Sendable diagnostics for iteration over async sequences.
1 parent e96dcac commit 3558237

File tree

3 files changed

+34
-3
lines changed

3 files changed

+34
-3
lines changed

lib/Sema/CSApply.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8234,6 +8234,10 @@ bool ExprRewriter::isDistributedThunk(ConcreteDeclRef ref, Expr *context) {
82348234
return existential.ExistentialValue;
82358235
}
82368236
return nullptr;
8237+
},
8238+
[]() -> VarDecl * {
8239+
// FIXME: Need to communicate this.
8240+
return nullptr;
82378241
});
82388242

82398243
if (!actor)

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2785,6 +2785,25 @@ namespace {
27852785
}
27862786
}
27872787
return nullptr;
2788+
},
2789+
[this]() -> VarDecl * {
2790+
auto isolation = getActorIsolationOfContext(
2791+
const_cast<DeclContext *>(getDeclContext()),
2792+
getClosureActorIsolation);
2793+
if (isolation == ActorIsolation::ActorInstance) {
2794+
VarDecl *var = isolation.getActorInstance();
2795+
if (!var) {
2796+
auto dc = const_cast<DeclContext *>(getDeclContext());
2797+
auto paramIdx = isolation.getActorInstanceParameter();
2798+
if (paramIdx == 0) {
2799+
var = cast<AbstractFunctionDecl>(dc)->getImplicitSelfDecl();
2800+
} else {
2801+
var = const_cast<ParamDecl *>(getParameterAt(dc, paramIdx - 1));
2802+
}
2803+
}
2804+
return var;
2805+
}
2806+
return nullptr;
27882807
});
27892808
}
27902809

@@ -3293,7 +3312,8 @@ namespace {
32933312
}
32943313

32953314
argForIsolatedParam = arg;
3296-
if (getIsolatedActor(arg))
3315+
unsatisfiedIsolation = llvm::None;
3316+
if (getIsolatedActor(arg) || isa<CurrentContextIsolationExpr>(arg))
32973317
continue;
32983318

32993319
// An isolated parameter was provided with a non-isolated argument.
@@ -6030,7 +6050,8 @@ AbstractFunctionDecl const *swift::isActorInitOrDeInitContext(
60306050
/// for the given expression.
60316051
VarDecl *swift::getReferencedParamOrCapture(
60326052
Expr *expr,
6033-
llvm::function_ref<Expr *(OpaqueValueExpr *)> getExistentialValue) {
6053+
llvm::function_ref<Expr *(OpaqueValueExpr *)> getExistentialValue,
6054+
llvm::function_ref<VarDecl *()> getCurrentIsolatedVar) {
60346055
// Look through identity expressions and implicit conversions.
60356056
Expr *prior;
60366057

@@ -6057,6 +6078,11 @@ VarDecl *swift::getReferencedParamOrCapture(
60576078
if (auto declRef = dyn_cast<DeclRefExpr>(expr))
60586079
return dyn_cast<VarDecl>(declRef->getDecl());
60596080

6081+
// The current context isolation expression (#isolation) always
6082+
// corresponds to the isolation of the given code.
6083+
if (isa<CurrentContextIsolationExpr>(expr))
6084+
return getCurrentIsolatedVar();
6085+
60606086
return nullptr;
60616087
}
60626088

lib/Sema/TypeCheckConcurrency.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -556,7 +556,8 @@ bool isThrowsDecl(ConcreteDeclRef declRef);
556556
/// for the given expression.
557557
VarDecl *getReferencedParamOrCapture(
558558
Expr *expr,
559-
llvm::function_ref<Expr *(OpaqueValueExpr *)> getExistentialValue);
559+
llvm::function_ref<Expr *(OpaqueValueExpr *)> getExistentialValue,
560+
llvm::function_ref<VarDecl *()> getCurrentIsolatedVar);
560561

561562
/// Determine whether the given value can be accessed across actors
562563
/// without from normal synchronous code.

0 commit comments

Comments
 (0)