@@ -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:
@@ -1564,6 +1568,9 @@ namespace {
1564
1568
SmallVector<ApplyExpr*, 4 > applyStack;
1565
1569
SmallVector<std::pair<OpaqueValueExpr *, Expr *>, 4 > opaqueValues;
1566
1570
SmallVector<const PatternBindingDecl *, 2 > patternBindingStack;
1571
+ llvm::function_ref<Type(Expr *)> getType;
1572
+ llvm::function_ref<ClosureActorIsolation(AbstractClosureExpr *)>
1573
+ getClosureActorIsolation;
1567
1574
1568
1575
// / Keeps track of the capture context of variables that have been
1569
1576
// / explicitly captured in closures.
@@ -1762,7 +1769,13 @@ namespace {
1762
1769
}
1763
1770
1764
1771
public:
1765
- ActorIsolationChecker (const DeclContext *dc) : ctx(dc->getASTContext ()) {
1772
+ ActorIsolationChecker (
1773
+ const DeclContext *dc,
1774
+ llvm::function_ref<Type(Expr *)> getType = __Expr_getType,
1775
+ llvm::function_ref<ClosureActorIsolation(AbstractClosureExpr *)>
1776
+ getClosureActorIsolation = __AbstractClosureExpr_getActorIsolation)
1777
+ : ctx(dc->getASTContext ()), getType(getType),
1778
+ getClosureActorIsolation(getClosureActorIsolation) {
1766
1779
contextStack.push_back (dc);
1767
1780
}
1768
1781
@@ -2062,7 +2075,7 @@ namespace {
2062
2075
break ;
2063
2076
2064
2077
if (auto closure = dyn_cast<AbstractClosureExpr>(dc)) {
2065
- auto isolation = closure-> getActorIsolation ( );
2078
+ auto isolation = getClosureActorIsolation (closure );
2066
2079
switch (isolation) {
2067
2080
case ClosureActorIsolation::Independent:
2068
2081
if (isSendableClosure (closure, /* forActorIsolation=*/ true )) {
@@ -2117,7 +2130,8 @@ namespace {
2117
2130
// Check isolation of the context itself. We do this separately
2118
2131
// from the closure check because closures capture specific variables
2119
2132
// while general isolation is declaration-based.
2120
- switch (auto isolation = getActorIsolationOfContext (dc)) {
2133
+ switch (auto isolation =
2134
+ getActorIsolationOfContext (dc, getClosureActorIsolation)) {
2121
2135
case ActorIsolation::Independent:
2122
2136
case ActorIsolation::Unspecified:
2123
2137
// Local functions can capture an isolated parameter.
@@ -2491,7 +2505,7 @@ namespace {
2491
2505
2492
2506
// / Check actor isolation for a particular application.
2493
2507
bool checkApply (ApplyExpr *apply) {
2494
- auto fnExprType = apply->getFn ()-> getType ( );
2508
+ auto fnExprType = getType ( apply->getFn ());
2495
2509
if (!fnExprType)
2496
2510
return false ;
2497
2511
@@ -2506,7 +2520,8 @@ namespace {
2506
2520
return *contextIsolation;
2507
2521
2508
2522
auto declContext = const_cast <DeclContext *>(getDeclContext ());
2509
- contextIsolation = getInnermostIsolatedContext (declContext);
2523
+ contextIsolation =
2524
+ getInnermostIsolatedContext (declContext, getClosureActorIsolation);
2510
2525
return *contextIsolation;
2511
2526
};
2512
2527
@@ -2542,9 +2557,9 @@ namespace {
2542
2557
// FIXME: The modeling of unsatisfiedIsolation is not great here.
2543
2558
// We'd be better off using something more like closure isolation
2544
2559
// that can talk about specific parameters.
2545
- auto nominal = arg-> getType ()->getAnyNominal ();
2560
+ auto nominal = getType (arg )->getAnyNominal ();
2546
2561
if (!nominal) {
2547
- nominal = arg-> getType ()->getASTContext ().getProtocol (
2562
+ nominal = getType (arg )->getASTContext ().getProtocol (
2548
2563
KnownProtocolKind::Actor);
2549
2564
}
2550
2565
@@ -2772,7 +2787,7 @@ namespace {
2772
2787
// where k is a captured dictionary key.
2773
2788
if (auto *args = component.getSubscriptArgs ()) {
2774
2789
for (auto arg : *args) {
2775
- auto type = arg.getExpr ()-> getType ( );
2790
+ auto type = getType ( arg.getExpr ());
2776
2791
if (type &&
2777
2792
shouldDiagnoseExistingDataRaces (getDeclContext ()) &&
2778
2793
diagnoseNonSendableTypes (
@@ -2805,8 +2820,8 @@ namespace {
2805
2820
if (base)
2806
2821
isolatedActor.emplace (getIsolatedActor (base));
2807
2822
auto result = ActorReferenceResult::forReference (
2808
- declRef, loc, getDeclContext (),
2809
- kindOfUsage (decl, context), isolatedActor );
2823
+ declRef, loc, getDeclContext (), kindOfUsage (decl, context),
2824
+ isolatedActor, None, None, getClosureActorIsolation );
2810
2825
switch (result) {
2811
2826
case ActorReferenceResult::SameConcurrencyDomain:
2812
2827
if (diagnoseReferenceToUnsafeGlobal (decl, loc))
@@ -2890,7 +2905,8 @@ namespace {
2890
2905
refKind = isolatedActor->kind ;
2891
2906
refGlobalActor = isolatedActor->globalActor ;
2892
2907
} else {
2893
- auto contextIsolation = getInnermostIsolatedContext (getDeclContext ());
2908
+ auto contextIsolation = getInnermostIsolatedContext (
2909
+ getDeclContext (), getClosureActorIsolation);
2894
2910
switch (contextIsolation) {
2895
2911
case ActorIsolation::ActorInstance:
2896
2912
refKind = ReferencedActor::Isolated;
@@ -2939,7 +2955,7 @@ namespace {
2939
2955
// Attempt to resolve the global actor type of a closure.
2940
2956
Type resolveGlobalActorType (ClosureExpr *closure) {
2941
2957
// Check whether the closure's type has a global actor already.
2942
- if (Type closureType = closure-> getType ()) {
2958
+ if (Type closureType = getType (closure )) {
2943
2959
if (auto closureFnType = closureType->getAs <FunctionType>()) {
2944
2960
if (Type globalActor = closureFnType->getGlobalActor ())
2945
2961
return globalActor;
@@ -2981,7 +2997,8 @@ namespace {
2981
2997
return ClosureActorIsolation::forIndependent (preconcurrency);
2982
2998
2983
2999
// A non-Sendable closure gets its isolation from its context.
2984
- auto parentIsolation = getActorIsolationOfContext (closure->getParent ());
3000
+ auto parentIsolation = getActorIsolationOfContext (
3001
+ closure->getParent (), getClosureActorIsolation);
2985
3002
preconcurrency |= parentIsolation.preconcurrency ();
2986
3003
2987
3004
// We must have parent isolation determined to get here.
@@ -3019,10 +3036,10 @@ bool ActorIsolationChecker::mayExecuteConcurrentlyWith(
3019
3036
// If both contexts are isolated to the same actor, then they will not
3020
3037
// execute concurrently.
3021
3038
auto useIsolation = getActorIsolationOfContext (
3022
- const_cast <DeclContext *>(useContext));
3039
+ const_cast <DeclContext *>(useContext), getClosureActorIsolation );
3023
3040
if (useIsolation.isActorIsolated ()) {
3024
3041
auto defIsolation = getActorIsolationOfContext (
3025
- const_cast <DeclContext *>(defContext));
3042
+ const_cast <DeclContext *>(defContext), getClosureActorIsolation );
3026
3043
if (useIsolation == defIsolation)
3027
3044
return false ;
3028
3045
}
@@ -3096,9 +3113,12 @@ void swift::checkPropertyWrapperActorIsolation(
3096
3113
expr->walk (checker);
3097
3114
}
3098
3115
3099
- ClosureActorIsolation
3100
- swift::determineClosureActorIsolation (AbstractClosureExpr *closure) {
3101
- ActorIsolationChecker checker (closure->getParent ());
3116
+ ClosureActorIsolation swift::determineClosureActorIsolation (
3117
+ AbstractClosureExpr *closure, llvm::function_ref<Type(Expr *)> getType,
3118
+ llvm::function_ref<ClosureActorIsolation(AbstractClosureExpr *)>
3119
+ getClosureActorIsolation) {
3120
+ ActorIsolationChecker checker (closure->getParent (), getType,
3121
+ getClosureActorIsolation);
3102
3122
return checker.determineClosureIsolation (closure);
3103
3123
}
3104
3124
@@ -5120,10 +5140,11 @@ static bool equivalentIsolationContexts(
5120
5140
5121
5141
ActorReferenceResult ActorReferenceResult::forReference (
5122
5142
ConcreteDeclRef declRef, SourceLoc declRefLoc, const DeclContext *fromDC,
5123
- Optional<VarRefUseEnv> useKind,
5124
- Optional<ReferencedActor> actorInstance,
5143
+ Optional<VarRefUseEnv> useKind, Optional<ReferencedActor> actorInstance,
5125
5144
Optional<ActorIsolation> knownDeclIsolation,
5126
- Optional<ActorIsolation> knownContextIsolation) {
5145
+ Optional<ActorIsolation> knownContextIsolation,
5146
+ llvm::function_ref<ClosureActorIsolation(AbstractClosureExpr *)>
5147
+ getClosureActorIsolation) {
5127
5148
// If not provided, compute the isolation of the declaration, adjusted
5128
5149
// for references.
5129
5150
ActorIsolation declIsolation = ActorIsolation::forUnspecified ();
@@ -5145,7 +5166,8 @@ ActorReferenceResult ActorReferenceResult::forReference(
5145
5166
if (knownContextIsolation) {
5146
5167
contextIsolation = *knownContextIsolation;
5147
5168
} else {
5148
- contextIsolation = getInnermostIsolatedContext (fromDC);
5169
+ contextIsolation =
5170
+ getInnermostIsolatedContext (fromDC, getClosureActorIsolation);
5149
5171
}
5150
5172
5151
5173
// When the declaration is not actor-isolated, it can always be accessed
0 commit comments