@@ -1477,10 +1477,14 @@ static bool checkedByFlowIsolation(DeclContext const *refCxt,
1477
1477
}
1478
1478
1479
1479
// / Get the actor isolation of the innermost relevant context.
1480
- static ActorIsolation getInnermostIsolatedContext (const DeclContext *dc) {
1480
+ static ActorIsolation getInnermostIsolatedContext (
1481
+ const DeclContext *dc,
1482
+ llvm::function_ref<ClosureActorIsolation(AbstractClosureExpr *)>
1483
+ getClosureActorIsolation) {
1481
1484
// Retrieve the actor isolation of the context.
1482
1485
auto mutableDC = const_cast <DeclContext *>(dc);
1483
- switch (auto isolation = getActorIsolationOfContext (mutableDC)) {
1486
+ switch (auto isolation =
1487
+ getActorIsolationOfContext (mutableDC, getClosureActorIsolation)) {
1484
1488
case ActorIsolation::ActorInstance:
1485
1489
case ActorIsolation::Independent:
1486
1490
case ActorIsolation::Unspecified:
@@ -1563,6 +1567,9 @@ namespace {
1563
1567
SmallVector<ApplyExpr*, 4 > applyStack;
1564
1568
SmallVector<std::pair<OpaqueValueExpr *, Expr *>, 4 > opaqueValues;
1565
1569
SmallVector<const PatternBindingDecl *, 2 > patternBindingStack;
1570
+ llvm::function_ref<Type(Expr *)> getType;
1571
+ llvm::function_ref<ClosureActorIsolation(AbstractClosureExpr *)>
1572
+ getClosureActorIsolation;
1566
1573
1567
1574
// / Keeps track of the capture context of variables that have been
1568
1575
// / explicitly captured in closures.
@@ -1761,7 +1768,13 @@ namespace {
1761
1768
}
1762
1769
1763
1770
public:
1764
- ActorIsolationChecker (const DeclContext *dc) : ctx(dc->getASTContext ()) {
1771
+ ActorIsolationChecker (
1772
+ const DeclContext *dc,
1773
+ llvm::function_ref<Type(Expr *)> getType = __Expr_getType,
1774
+ llvm::function_ref<ClosureActorIsolation(AbstractClosureExpr *)>
1775
+ getClosureActorIsolation = __AbstractClosureExpr_getActorIsolation)
1776
+ : ctx(dc->getASTContext ()), getType(getType),
1777
+ getClosureActorIsolation(getClosureActorIsolation) {
1765
1778
contextStack.push_back (dc);
1766
1779
}
1767
1780
@@ -2061,7 +2074,7 @@ namespace {
2061
2074
break ;
2062
2075
2063
2076
if (auto closure = dyn_cast<AbstractClosureExpr>(dc)) {
2064
- auto isolation = closure-> getActorIsolation ( );
2077
+ auto isolation = getClosureActorIsolation (closure );
2065
2078
switch (isolation) {
2066
2079
case ClosureActorIsolation::Independent:
2067
2080
if (isSendableClosure (closure, /* forActorIsolation=*/ true )) {
@@ -2116,7 +2129,8 @@ namespace {
2116
2129
// Check isolation of the context itself. We do this separately
2117
2130
// from the closure check because closures capture specific variables
2118
2131
// while general isolation is declaration-based.
2119
- switch (auto isolation = getActorIsolationOfContext (dc)) {
2132
+ switch (auto isolation =
2133
+ getActorIsolationOfContext (dc, getClosureActorIsolation)) {
2120
2134
case ActorIsolation::Independent:
2121
2135
case ActorIsolation::Unspecified:
2122
2136
// Local functions can capture an isolated parameter.
@@ -2490,7 +2504,7 @@ namespace {
2490
2504
2491
2505
// / Check actor isolation for a particular application.
2492
2506
bool checkApply (ApplyExpr *apply) {
2493
- auto fnExprType = apply->getFn ()-> getType ( );
2507
+ auto fnExprType = getType ( apply->getFn ());
2494
2508
if (!fnExprType)
2495
2509
return false ;
2496
2510
@@ -2505,7 +2519,8 @@ namespace {
2505
2519
return *contextIsolation;
2506
2520
2507
2521
auto declContext = const_cast <DeclContext *>(getDeclContext ());
2508
- contextIsolation = getInnermostIsolatedContext (declContext);
2522
+ contextIsolation =
2523
+ getInnermostIsolatedContext (declContext, getClosureActorIsolation);
2509
2524
return *contextIsolation;
2510
2525
};
2511
2526
@@ -2541,9 +2556,9 @@ namespace {
2541
2556
// FIXME: The modeling of unsatisfiedIsolation is not great here.
2542
2557
// We'd be better off using something more like closure isolation
2543
2558
// that can talk about specific parameters.
2544
- auto nominal = arg-> getType ()->getAnyNominal ();
2559
+ auto nominal = getType (arg )->getAnyNominal ();
2545
2560
if (!nominal) {
2546
- nominal = arg-> getType ()->getASTContext ().getProtocol (
2561
+ nominal = getType (arg )->getASTContext ().getProtocol (
2547
2562
KnownProtocolKind::Actor);
2548
2563
}
2549
2564
@@ -2771,7 +2786,7 @@ namespace {
2771
2786
// where k is a captured dictionary key.
2772
2787
if (auto *args = component.getSubscriptArgs ()) {
2773
2788
for (auto arg : *args) {
2774
- auto type = arg.getExpr ()-> getType ( );
2789
+ auto type = getType ( arg.getExpr ());
2775
2790
if (type &&
2776
2791
shouldDiagnoseExistingDataRaces (getDeclContext ()) &&
2777
2792
diagnoseNonSendableTypes (
@@ -2804,8 +2819,8 @@ namespace {
2804
2819
if (base)
2805
2820
isolatedActor.emplace (getIsolatedActor (base));
2806
2821
auto result = ActorReferenceResult::forReference (
2807
- declRef, loc, getDeclContext (),
2808
- kindOfUsage (decl, context), isolatedActor );
2822
+ declRef, loc, getDeclContext (), kindOfUsage (decl, context),
2823
+ isolatedActor, None, None, getClosureActorIsolation );
2809
2824
switch (result) {
2810
2825
case ActorReferenceResult::SameConcurrencyDomain:
2811
2826
if (diagnoseReferenceToUnsafeGlobal (decl, loc))
@@ -2889,7 +2904,8 @@ namespace {
2889
2904
refKind = isolatedActor->kind ;
2890
2905
refGlobalActor = isolatedActor->globalActor ;
2891
2906
} else {
2892
- auto contextIsolation = getInnermostIsolatedContext (getDeclContext ());
2907
+ auto contextIsolation = getInnermostIsolatedContext (
2908
+ getDeclContext (), getClosureActorIsolation);
2893
2909
switch (contextIsolation) {
2894
2910
case ActorIsolation::ActorInstance:
2895
2911
refKind = ReferencedActor::Isolated;
@@ -2938,7 +2954,7 @@ namespace {
2938
2954
// Attempt to resolve the global actor type of a closure.
2939
2955
Type resolveGlobalActorType (ClosureExpr *closure) {
2940
2956
// Check whether the closure's type has a global actor already.
2941
- if (Type closureType = closure-> getType ()) {
2957
+ if (Type closureType = getType (closure )) {
2942
2958
if (auto closureFnType = closureType->getAs <FunctionType>()) {
2943
2959
if (Type globalActor = closureFnType->getGlobalActor ())
2944
2960
return globalActor;
@@ -2980,7 +2996,8 @@ namespace {
2980
2996
return ClosureActorIsolation::forIndependent (preconcurrency);
2981
2997
2982
2998
// A non-Sendable closure gets its isolation from its context.
2983
- auto parentIsolation = getActorIsolationOfContext (closure->getParent ());
2999
+ auto parentIsolation = getActorIsolationOfContext (
3000
+ closure->getParent (), getClosureActorIsolation);
2984
3001
preconcurrency |= parentIsolation.preconcurrency ();
2985
3002
2986
3003
// We must have parent isolation determined to get here.
@@ -3018,10 +3035,10 @@ bool ActorIsolationChecker::mayExecuteConcurrentlyWith(
3018
3035
// If both contexts are isolated to the same actor, then they will not
3019
3036
// execute concurrently.
3020
3037
auto useIsolation = getActorIsolationOfContext (
3021
- const_cast <DeclContext *>(useContext));
3038
+ const_cast <DeclContext *>(useContext), getClosureActorIsolation );
3022
3039
if (useIsolation.isActorIsolated ()) {
3023
3040
auto defIsolation = getActorIsolationOfContext (
3024
- const_cast <DeclContext *>(defContext));
3041
+ const_cast <DeclContext *>(defContext), getClosureActorIsolation );
3025
3042
if (useIsolation == defIsolation)
3026
3043
return false ;
3027
3044
}
@@ -3095,9 +3112,12 @@ void swift::checkPropertyWrapperActorIsolation(
3095
3112
expr->walk (checker);
3096
3113
}
3097
3114
3098
- ClosureActorIsolation
3099
- swift::determineClosureActorIsolation (AbstractClosureExpr *closure) {
3100
- ActorIsolationChecker checker (closure->getParent ());
3115
+ ClosureActorIsolation swift::determineClosureActorIsolation (
3116
+ AbstractClosureExpr *closure, llvm::function_ref<Type(Expr *)> getType,
3117
+ llvm::function_ref<ClosureActorIsolation(AbstractClosureExpr *)>
3118
+ getClosureActorIsolation) {
3119
+ ActorIsolationChecker checker (closure->getParent (), getType,
3120
+ getClosureActorIsolation);
3101
3121
return checker.determineClosureIsolation (closure);
3102
3122
}
3103
3123
@@ -3835,14 +3855,14 @@ ActorIsolation ActorIsolationRequest::evaluate(
3835
3855
// If this is a defer body, inherit unconditionally; we don't
3836
3856
// care if the enclosing function captures the isolated parameter.
3837
3857
if (func->isDeferBody ()) {
3838
- auto enclosingIsolation =
3839
- getActorIsolationOfContext ( func->getDeclContext ());
3858
+ auto enclosingIsolation = getActorIsolationOfContext (
3859
+ func->getDeclContext ());
3840
3860
return inferredIsolation (enclosingIsolation);
3841
3861
}
3842
3862
3843
3863
if (func->isLocalCapture () && !func->isSendable ()) {
3844
- switch (auto enclosingIsolation =
3845
- getActorIsolationOfContext ( func->getDeclContext ())) {
3864
+ switch (auto enclosingIsolation = getActorIsolationOfContext (
3865
+ func->getDeclContext ())) {
3846
3866
case ActorIsolation::Independent:
3847
3867
case ActorIsolation::Unspecified:
3848
3868
// Do nothing.
@@ -5127,10 +5147,11 @@ static bool equivalentIsolationContexts(
5127
5147
5128
5148
ActorReferenceResult ActorReferenceResult::forReference (
5129
5149
ConcreteDeclRef declRef, SourceLoc declRefLoc, const DeclContext *fromDC,
5130
- Optional<VarRefUseEnv> useKind,
5131
- Optional<ReferencedActor> actorInstance,
5150
+ Optional<VarRefUseEnv> useKind, Optional<ReferencedActor> actorInstance,
5132
5151
Optional<ActorIsolation> knownDeclIsolation,
5133
- Optional<ActorIsolation> knownContextIsolation) {
5152
+ Optional<ActorIsolation> knownContextIsolation,
5153
+ llvm::function_ref<ClosureActorIsolation(AbstractClosureExpr *)>
5154
+ getClosureActorIsolation) {
5134
5155
// If not provided, compute the isolation of the declaration, adjusted
5135
5156
// for references.
5136
5157
ActorIsolation declIsolation = ActorIsolation::forUnspecified ();
@@ -5152,7 +5173,8 @@ ActorReferenceResult ActorReferenceResult::forReference(
5152
5173
if (knownContextIsolation) {
5153
5174
contextIsolation = *knownContextIsolation;
5154
5175
} else {
5155
- contextIsolation = getInnermostIsolatedContext (fromDC);
5176
+ contextIsolation =
5177
+ getInnermostIsolatedContext (fromDC, getClosureActorIsolation);
5156
5178
}
5157
5179
5158
5180
// When the declaration is not actor-isolated, it can always be accessed
0 commit comments