@@ -1474,10 +1474,14 @@ static bool checkedByFlowIsolation(DeclContext const *refCxt,
1474
1474
}
1475
1475
1476
1476
// / Get the actor isolation of the innermost relevant context.
1477
- static ActorIsolation getInnermostIsolatedContext (const DeclContext *dc) {
1477
+ static ActorIsolation getInnermostIsolatedContext (
1478
+ const DeclContext *dc,
1479
+ llvm::function_ref<ClosureActorIsolation(AbstractClosureExpr *)>
1480
+ getClosureActorIsolation) {
1478
1481
// Retrieve the actor isolation of the context.
1479
1482
auto mutableDC = const_cast <DeclContext *>(dc);
1480
- switch (auto isolation = getActorIsolationOfContext (mutableDC)) {
1483
+ switch (auto isolation =
1484
+ getActorIsolationOfContext (mutableDC, getClosureActorIsolation)) {
1481
1485
case ActorIsolation::ActorInstance:
1482
1486
case ActorIsolation::Independent:
1483
1487
case ActorIsolation::Unspecified:
@@ -1560,6 +1564,9 @@ namespace {
1560
1564
SmallVector<ApplyExpr*, 4 > applyStack;
1561
1565
SmallVector<std::pair<OpaqueValueExpr *, Expr *>, 4 > opaqueValues;
1562
1566
SmallVector<const PatternBindingDecl *, 2 > patternBindingStack;
1567
+ llvm::function_ref<Type(Expr *)> getType;
1568
+ llvm::function_ref<ClosureActorIsolation(AbstractClosureExpr *)>
1569
+ getClosureActorIsolation;
1563
1570
1564
1571
// / Keeps track of the capture context of variables that have been
1565
1572
// / explicitly captured in closures.
@@ -1758,7 +1765,13 @@ namespace {
1758
1765
}
1759
1766
1760
1767
public:
1761
- ActorIsolationChecker (const DeclContext *dc) : ctx(dc->getASTContext ()) {
1768
+ ActorIsolationChecker (
1769
+ const DeclContext *dc,
1770
+ llvm::function_ref<Type(Expr *)> getType = __Expr_getType,
1771
+ llvm::function_ref<ClosureActorIsolation(AbstractClosureExpr *)>
1772
+ getClosureActorIsolation = __AbstractClosureExpr_getActorIsolation)
1773
+ : ctx(dc->getASTContext ()), getType(getType),
1774
+ getClosureActorIsolation(getClosureActorIsolation) {
1762
1775
contextStack.push_back (dc);
1763
1776
}
1764
1777
@@ -2058,7 +2071,7 @@ namespace {
2058
2071
break ;
2059
2072
2060
2073
if (auto closure = dyn_cast<AbstractClosureExpr>(dc)) {
2061
- auto isolation = closure-> getActorIsolation ( );
2074
+ auto isolation = getClosureActorIsolation (closure );
2062
2075
switch (isolation) {
2063
2076
case ClosureActorIsolation::Independent:
2064
2077
if (isSendableClosure (closure, /* forActorIsolation=*/ true )) {
@@ -2113,7 +2126,8 @@ namespace {
2113
2126
// Check isolation of the context itself. We do this separately
2114
2127
// from the closure check because closures capture specific variables
2115
2128
// while general isolation is declaration-based.
2116
- switch (auto isolation = getActorIsolationOfContext (dc)) {
2129
+ switch (auto isolation =
2130
+ getActorIsolationOfContext (dc, getClosureActorIsolation)) {
2117
2131
case ActorIsolation::Independent:
2118
2132
case ActorIsolation::Unspecified:
2119
2133
// Local functions can capture an isolated parameter.
@@ -2487,7 +2501,7 @@ namespace {
2487
2501
2488
2502
// / Check actor isolation for a particular application.
2489
2503
bool checkApply (ApplyExpr *apply) {
2490
- auto fnExprType = apply->getFn ()-> getType ( );
2504
+ auto fnExprType = getType ( apply->getFn ());
2491
2505
if (!fnExprType)
2492
2506
return false ;
2493
2507
@@ -2502,7 +2516,8 @@ namespace {
2502
2516
return *contextIsolation;
2503
2517
2504
2518
auto declContext = const_cast <DeclContext *>(getDeclContext ());
2505
- contextIsolation = getInnermostIsolatedContext (declContext);
2519
+ contextIsolation =
2520
+ getInnermostIsolatedContext (declContext, getClosureActorIsolation);
2506
2521
return *contextIsolation;
2507
2522
};
2508
2523
@@ -2539,9 +2554,9 @@ namespace {
2539
2554
// FIXME: The modeling of unsatisfiedIsolation is not great here.
2540
2555
// We'd be better off using something more like closure isolation
2541
2556
// that can talk about specific parameters.
2542
- auto nominal = arg-> getType ()->getAnyNominal ();
2557
+ auto nominal = getType (arg )->getAnyNominal ();
2543
2558
if (!nominal) {
2544
- nominal = arg-> getType ()->getASTContext ().getProtocol (
2559
+ nominal = getType (arg )->getASTContext ().getProtocol (
2545
2560
KnownProtocolKind::Actor);
2546
2561
}
2547
2562
@@ -2785,7 +2800,7 @@ namespace {
2785
2800
// where k is a captured dictionary key.
2786
2801
if (auto *args = component.getSubscriptArgs ()) {
2787
2802
for (auto arg : *args) {
2788
- auto type = arg.getExpr ()-> getType ( );
2803
+ auto type = getType ( arg.getExpr ());
2789
2804
if (type &&
2790
2805
shouldDiagnoseExistingDataRaces (getDeclContext ()) &&
2791
2806
diagnoseNonSendableTypes (
@@ -2818,8 +2833,8 @@ namespace {
2818
2833
if (base)
2819
2834
isolatedActor.emplace (getIsolatedActor (base));
2820
2835
auto result = ActorReferenceResult::forReference (
2821
- declRef, loc, getDeclContext (),
2822
- kindOfUsage (decl, context), isolatedActor );
2836
+ declRef, loc, getDeclContext (), kindOfUsage (decl, context),
2837
+ isolatedActor, None, None, getClosureActorIsolation );
2823
2838
switch (result) {
2824
2839
case ActorReferenceResult::SameConcurrencyDomain:
2825
2840
if (diagnoseReferenceToUnsafeGlobal (decl, loc))
@@ -2903,7 +2918,8 @@ namespace {
2903
2918
refKind = isolatedActor->kind ;
2904
2919
refGlobalActor = isolatedActor->globalActor ;
2905
2920
} else {
2906
- auto contextIsolation = getInnermostIsolatedContext (getDeclContext ());
2921
+ auto contextIsolation = getInnermostIsolatedContext (
2922
+ getDeclContext (), getClosureActorIsolation);
2907
2923
switch (contextIsolation) {
2908
2924
case ActorIsolation::ActorInstance:
2909
2925
refKind = ReferencedActor::Isolated;
@@ -2952,7 +2968,7 @@ namespace {
2952
2968
// Attempt to resolve the global actor type of a closure.
2953
2969
Type resolveGlobalActorType (ClosureExpr *closure) {
2954
2970
// Check whether the closure's type has a global actor already.
2955
- if (Type closureType = closure-> getType ()) {
2971
+ if (Type closureType = getType (closure )) {
2956
2972
if (auto closureFnType = closureType->getAs <FunctionType>()) {
2957
2973
if (Type globalActor = closureFnType->getGlobalActor ())
2958
2974
return globalActor;
@@ -2994,7 +3010,8 @@ namespace {
2994
3010
return ClosureActorIsolation::forIndependent (preconcurrency);
2995
3011
2996
3012
// A non-Sendable closure gets its isolation from its context.
2997
- auto parentIsolation = getActorIsolationOfContext (closure->getParent ());
3013
+ auto parentIsolation = getActorIsolationOfContext (
3014
+ closure->getParent (), getClosureActorIsolation);
2998
3015
preconcurrency |= parentIsolation.preconcurrency ();
2999
3016
3000
3017
// We must have parent isolation determined to get here.
@@ -3032,10 +3049,10 @@ bool ActorIsolationChecker::mayExecuteConcurrentlyWith(
3032
3049
// If both contexts are isolated to the same actor, then they will not
3033
3050
// execute concurrently.
3034
3051
auto useIsolation = getActorIsolationOfContext (
3035
- const_cast <DeclContext *>(useContext));
3052
+ const_cast <DeclContext *>(useContext), getClosureActorIsolation );
3036
3053
if (useIsolation.isActorIsolated ()) {
3037
3054
auto defIsolation = getActorIsolationOfContext (
3038
- const_cast <DeclContext *>(defContext));
3055
+ const_cast <DeclContext *>(defContext), getClosureActorIsolation );
3039
3056
if (useIsolation == defIsolation)
3040
3057
return false ;
3041
3058
}
@@ -3109,9 +3126,12 @@ void swift::checkPropertyWrapperActorIsolation(
3109
3126
expr->walk (checker);
3110
3127
}
3111
3128
3112
- ClosureActorIsolation
3113
- swift::determineClosureActorIsolation (AbstractClosureExpr *closure) {
3114
- ActorIsolationChecker checker (closure->getParent ());
3129
+ ClosureActorIsolation swift::determineClosureActorIsolation (
3130
+ AbstractClosureExpr *closure, llvm::function_ref<Type(Expr *)> getType,
3131
+ llvm::function_ref<ClosureActorIsolation(AbstractClosureExpr *)>
3132
+ getClosureActorIsolation) {
3133
+ ActorIsolationChecker checker (closure->getParent (), getType,
3134
+ getClosureActorIsolation);
3115
3135
return checker.determineClosureIsolation (closure);
3116
3136
}
3117
3137
@@ -3801,14 +3821,14 @@ ActorIsolation ActorIsolationRequest::evaluate(
3801
3821
// If this is a defer body, inherit unconditionally; we don't
3802
3822
// care if the enclosing function captures the isolated parameter.
3803
3823
if (func->isDeferBody ()) {
3804
- auto enclosingIsolation =
3805
- getActorIsolationOfContext ( func->getDeclContext ());
3824
+ auto enclosingIsolation = getActorIsolationOfContext (
3825
+ func->getDeclContext ());
3806
3826
return inferredIsolation (enclosingIsolation);
3807
3827
}
3808
3828
3809
3829
if (func->isLocalCapture () && !func->isSendable ()) {
3810
- switch (auto enclosingIsolation =
3811
- getActorIsolationOfContext ( func->getDeclContext ())) {
3830
+ switch (auto enclosingIsolation = getActorIsolationOfContext (
3831
+ func->getDeclContext ())) {
3812
3832
case ActorIsolation::Independent:
3813
3833
case ActorIsolation::Unspecified:
3814
3834
// Do nothing.
@@ -5092,10 +5112,11 @@ static bool equivalentIsolationContexts(
5092
5112
5093
5113
ActorReferenceResult ActorReferenceResult::forReference (
5094
5114
ConcreteDeclRef declRef, SourceLoc declRefLoc, const DeclContext *fromDC,
5095
- Optional<VarRefUseEnv> useKind,
5096
- Optional<ReferencedActor> actorInstance,
5115
+ Optional<VarRefUseEnv> useKind, Optional<ReferencedActor> actorInstance,
5097
5116
Optional<ActorIsolation> knownDeclIsolation,
5098
- Optional<ActorIsolation> knownContextIsolation) {
5117
+ Optional<ActorIsolation> knownContextIsolation,
5118
+ llvm::function_ref<ClosureActorIsolation(AbstractClosureExpr *)>
5119
+ getClosureActorIsolation) {
5099
5120
// If not provided, compute the isolation of the declaration, adjusted
5100
5121
// for references.
5101
5122
ActorIsolation declIsolation = ActorIsolation::forUnspecified ();
@@ -5117,7 +5138,8 @@ ActorReferenceResult ActorReferenceResult::forReference(
5117
5138
if (knownContextIsolation) {
5118
5139
contextIsolation = *knownContextIsolation;
5119
5140
} else {
5120
- contextIsolation = getInnermostIsolatedContext (fromDC);
5141
+ contextIsolation =
5142
+ getInnermostIsolatedContext (fromDC, getClosureActorIsolation);
5121
5143
}
5122
5144
5123
5145
// When the declaration is not actor-isolated, it can always be accessed
0 commit comments