31
31
32
32
using namespace swift ;
33
33
34
+ ClosureActorIsolation
35
+ swift::__AbstractClosureExpr_getActorIsolation (AbstractClosureExpr *CE) {
36
+ return CE->getActorIsolation ();
37
+ }
38
+
34
39
// / Determine whether it makes sense to infer an attribute in the given
35
40
// / context.
36
41
static bool shouldInferAttributeInContext (const DeclContext *dc) {
@@ -1462,10 +1467,14 @@ static bool checkedByFlowIsolation(DeclContext const *refCxt,
1462
1467
}
1463
1468
1464
1469
// / Get the actor isolation of the innermost relevant context.
1465
- static ActorIsolation getInnermostIsolatedContext (const DeclContext *dc) {
1470
+ static ActorIsolation getInnermostIsolatedContext (
1471
+ const DeclContext *dc,
1472
+ llvm::function_ref<ClosureActorIsolation(AbstractClosureExpr *)>
1473
+ getClosureActorIsolation) {
1466
1474
// Retrieve the actor isolation of the context.
1467
1475
auto mutableDC = const_cast <DeclContext *>(dc);
1468
- switch (auto isolation = getActorIsolationOfContext (mutableDC)) {
1476
+ switch (auto isolation =
1477
+ getActorIsolationOfContext (mutableDC, getClosureActorIsolation)) {
1469
1478
case ActorIsolation::ActorInstance:
1470
1479
case ActorIsolation::Independent:
1471
1480
case ActorIsolation::Unspecified:
@@ -1548,6 +1557,9 @@ namespace {
1548
1557
SmallVector<ApplyExpr*, 4 > applyStack;
1549
1558
SmallVector<std::pair<OpaqueValueExpr *, Expr *>, 4 > opaqueValues;
1550
1559
SmallVector<const PatternBindingDecl *, 2 > patternBindingStack;
1560
+ llvm::function_ref<Type(Expr *)> getType;
1561
+ llvm::function_ref<ClosureActorIsolation(AbstractClosureExpr *)>
1562
+ getClosureActorIsolation;
1551
1563
1552
1564
// / Keeps track of the capture context of variables that have been
1553
1565
// / explicitly captured in closures.
@@ -1746,7 +1758,13 @@ namespace {
1746
1758
}
1747
1759
1748
1760
public:
1749
- ActorIsolationChecker (const DeclContext *dc) : ctx(dc->getASTContext ()) {
1761
+ ActorIsolationChecker (
1762
+ const DeclContext *dc,
1763
+ llvm::function_ref<Type(Expr *)> getType = __Expr_getType,
1764
+ llvm::function_ref<ClosureActorIsolation(AbstractClosureExpr *)>
1765
+ getClosureActorIsolation = __AbstractClosureExpr_getActorIsolation)
1766
+ : ctx(dc->getASTContext ()), getType(getType),
1767
+ getClosureActorIsolation(getClosureActorIsolation) {
1750
1768
contextStack.push_back (dc);
1751
1769
}
1752
1770
@@ -2046,7 +2064,7 @@ namespace {
2046
2064
break ;
2047
2065
2048
2066
if (auto closure = dyn_cast<AbstractClosureExpr>(dc)) {
2049
- auto isolation = closure-> getActorIsolation ( );
2067
+ auto isolation = getClosureActorIsolation (closure );
2050
2068
switch (isolation) {
2051
2069
case ClosureActorIsolation::Independent:
2052
2070
if (isSendableClosure (closure, /* forActorIsolation=*/ true )) {
@@ -2101,7 +2119,8 @@ namespace {
2101
2119
// Check isolation of the context itself. We do this separately
2102
2120
// from the closure check because closures capture specific variables
2103
2121
// while general isolation is declaration-based.
2104
- switch (auto isolation = getActorIsolationOfContext (dc)) {
2122
+ switch (auto isolation =
2123
+ getActorIsolationOfContext (dc, getClosureActorIsolation)) {
2105
2124
case ActorIsolation::Independent:
2106
2125
case ActorIsolation::Unspecified:
2107
2126
// Local functions can capture an isolated parameter.
@@ -2475,7 +2494,7 @@ namespace {
2475
2494
2476
2495
// / Check actor isolation for a particular application.
2477
2496
bool checkApply (ApplyExpr *apply) {
2478
- auto fnExprType = apply->getFn ()-> getType ( );
2497
+ auto fnExprType = getType ( apply->getFn ());
2479
2498
if (!fnExprType)
2480
2499
return false ;
2481
2500
@@ -2490,7 +2509,8 @@ namespace {
2490
2509
return *contextIsolation;
2491
2510
2492
2511
auto declContext = const_cast <DeclContext *>(getDeclContext ());
2493
- contextIsolation = getInnermostIsolatedContext (declContext);
2512
+ contextIsolation =
2513
+ getInnermostIsolatedContext (declContext, getClosureActorIsolation);
2494
2514
return *contextIsolation;
2495
2515
};
2496
2516
@@ -2527,9 +2547,9 @@ namespace {
2527
2547
// FIXME: The modeling of unsatisfiedIsolation is not great here.
2528
2548
// We'd be better off using something more like closure isolation
2529
2549
// that can talk about specific parameters.
2530
- auto nominal = arg-> getType ()->getAnyNominal ();
2550
+ auto nominal = getType (arg )->getAnyNominal ();
2531
2551
if (!nominal) {
2532
- nominal = arg-> getType ()->getASTContext ().getProtocol (
2552
+ nominal = getType (arg )->getASTContext ().getProtocol (
2533
2553
KnownProtocolKind::Actor);
2534
2554
}
2535
2555
@@ -2768,7 +2788,7 @@ namespace {
2768
2788
// where k is a captured dictionary key.
2769
2789
if (auto *args = component.getSubscriptArgs ()) {
2770
2790
for (auto arg : *args) {
2771
- auto type = arg.getExpr ()-> getType ( );
2791
+ auto type = getType ( arg.getExpr ());
2772
2792
if (type &&
2773
2793
shouldDiagnoseExistingDataRaces (getDeclContext ()) &&
2774
2794
diagnoseNonSendableTypes (
@@ -2801,8 +2821,8 @@ namespace {
2801
2821
if (base)
2802
2822
isolatedActor.emplace (getIsolatedActor (base));
2803
2823
auto result = ActorReferenceResult::forReference (
2804
- declRef, loc, getDeclContext (),
2805
- kindOfUsage (decl, context), isolatedActor );
2824
+ declRef, loc, getDeclContext (), kindOfUsage (decl, context),
2825
+ isolatedActor, None, None, getClosureActorIsolation );
2806
2826
switch (result) {
2807
2827
case ActorReferenceResult::SameConcurrencyDomain:
2808
2828
if (diagnoseReferenceToUnsafeGlobal (decl, loc))
@@ -2886,7 +2906,8 @@ namespace {
2886
2906
refKind = isolatedActor->kind ;
2887
2907
refGlobalActor = isolatedActor->globalActor ;
2888
2908
} else {
2889
- auto contextIsolation = getInnermostIsolatedContext (getDeclContext ());
2909
+ auto contextIsolation = getInnermostIsolatedContext (
2910
+ getDeclContext (), getClosureActorIsolation);
2890
2911
switch (contextIsolation) {
2891
2912
case ActorIsolation::ActorInstance:
2892
2913
refKind = ReferencedActor::Isolated;
@@ -2930,7 +2951,7 @@ namespace {
2930
2951
// Attempt to resolve the global actor type of a closure.
2931
2952
Type resolveGlobalActorType (ClosureExpr *closure) {
2932
2953
// Check whether the closure's type has a global actor already.
2933
- if (Type closureType = closure-> getType ()) {
2954
+ if (Type closureType = getType (closure )) {
2934
2955
if (auto closureFnType = closureType->getAs <FunctionType>()) {
2935
2956
if (Type globalActor = closureFnType->getGlobalActor ())
2936
2957
return globalActor;
@@ -2972,7 +2993,8 @@ namespace {
2972
2993
return ClosureActorIsolation::forIndependent (preconcurrency);
2973
2994
2974
2995
// A non-Sendable closure gets its isolation from its context.
2975
- auto parentIsolation = getActorIsolationOfContext (closure->getParent ());
2996
+ auto parentIsolation = getActorIsolationOfContext (
2997
+ closure->getParent (), getClosureActorIsolation);
2976
2998
preconcurrency |= parentIsolation.preconcurrency ();
2977
2999
2978
3000
// We must have parent isolation determined to get here.
@@ -3010,10 +3032,10 @@ bool ActorIsolationChecker::mayExecuteConcurrentlyWith(
3010
3032
// If both contexts are isolated to the same actor, then they will not
3011
3033
// execute concurrently.
3012
3034
auto useIsolation = getActorIsolationOfContext (
3013
- const_cast <DeclContext *>(useContext));
3035
+ const_cast <DeclContext *>(useContext), getClosureActorIsolation );
3014
3036
if (useIsolation.isActorIsolated ()) {
3015
3037
auto defIsolation = getActorIsolationOfContext (
3016
- const_cast <DeclContext *>(defContext));
3038
+ const_cast <DeclContext *>(defContext), getClosureActorIsolation );
3017
3039
if (useIsolation == defIsolation)
3018
3040
return false ;
3019
3041
}
@@ -3087,9 +3109,12 @@ void swift::checkPropertyWrapperActorIsolation(
3087
3109
expr->walk (checker);
3088
3110
}
3089
3111
3090
- ClosureActorIsolation
3091
- swift::determineClosureActorIsolation (AbstractClosureExpr *closure) {
3092
- ActorIsolationChecker checker (closure->getParent ());
3112
+ ClosureActorIsolation swift::determineClosureActorIsolation (
3113
+ AbstractClosureExpr *closure, llvm::function_ref<Type(Expr *)> getType,
3114
+ llvm::function_ref<ClosureActorIsolation(AbstractClosureExpr *)>
3115
+ getClosureActorIsolation) {
3116
+ ActorIsolationChecker checker (closure->getParent (), getType,
3117
+ getClosureActorIsolation);
3093
3118
return checker.determineClosureIsolation (closure);
3094
3119
}
3095
3120
@@ -3779,14 +3804,15 @@ ActorIsolation ActorIsolationRequest::evaluate(
3779
3804
// If this is a defer body, inherit unconditionally; we don't
3780
3805
// care if the enclosing function captures the isolated parameter.
3781
3806
if (func->isDeferBody ()) {
3782
- auto enclosingIsolation =
3783
- getActorIsolationOfContext ( func->getDeclContext ());
3807
+ auto enclosingIsolation = getActorIsolationOfContext (
3808
+ func->getDeclContext (), __AbstractClosureExpr_getActorIsolation );
3784
3809
return inferredIsolation (enclosingIsolation);
3785
3810
}
3786
3811
3787
3812
if (func->isLocalCapture () && !func->isSendable ()) {
3788
- switch (auto enclosingIsolation =
3789
- getActorIsolationOfContext (func->getDeclContext ())) {
3813
+ switch (auto enclosingIsolation = getActorIsolationOfContext (
3814
+ func->getDeclContext (),
3815
+ __AbstractClosureExpr_getActorIsolation)) {
3790
3816
case ActorIsolation::Independent:
3791
3817
case ActorIsolation::Unspecified:
3792
3818
// Do nothing.
@@ -5045,10 +5071,11 @@ static bool equivalentIsolationContexts(
5045
5071
5046
5072
ActorReferenceResult ActorReferenceResult::forReference (
5047
5073
ConcreteDeclRef declRef, SourceLoc declRefLoc, const DeclContext *fromDC,
5048
- Optional<VarRefUseEnv> useKind,
5049
- Optional<ReferencedActor> actorInstance,
5074
+ Optional<VarRefUseEnv> useKind, Optional<ReferencedActor> actorInstance,
5050
5075
Optional<ActorIsolation> knownDeclIsolation,
5051
- Optional<ActorIsolation> knownContextIsolation) {
5076
+ Optional<ActorIsolation> knownContextIsolation,
5077
+ llvm::function_ref<ClosureActorIsolation(AbstractClosureExpr *)>
5078
+ getClosureActorIsolation) {
5052
5079
// If not provided, compute the isolation of the declaration, adjusted
5053
5080
// for references.
5054
5081
ActorIsolation declIsolation = ActorIsolation::forUnspecified ();
@@ -5070,7 +5097,8 @@ ActorReferenceResult ActorReferenceResult::forReference(
5070
5097
if (knownContextIsolation) {
5071
5098
contextIsolation = *knownContextIsolation;
5072
5099
} else {
5073
- contextIsolation = getInnermostIsolatedContext (fromDC);
5100
+ contextIsolation =
5101
+ getInnermostIsolatedContext (fromDC, getClosureActorIsolation);
5074
5102
}
5075
5103
5076
5104
// When the declaration is not actor-isolated, it can always be accessed
0 commit comments