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) {
@@ -1474,10 +1479,14 @@ static bool checkedByFlowIsolation(DeclContext const *refCxt,
1474
1479
}
1475
1480
1476
1481
// / Get the actor isolation of the innermost relevant context.
1477
- static ActorIsolation getInnermostIsolatedContext (const DeclContext *dc) {
1482
+ static ActorIsolation getInnermostIsolatedContext (
1483
+ const DeclContext *dc,
1484
+ llvm::function_ref<ClosureActorIsolation(AbstractClosureExpr *)>
1485
+ getClosureActorIsolation) {
1478
1486
// Retrieve the actor isolation of the context.
1479
1487
auto mutableDC = const_cast <DeclContext *>(dc);
1480
- switch (auto isolation = getActorIsolationOfContext (mutableDC)) {
1488
+ switch (auto isolation =
1489
+ getActorIsolationOfContext (mutableDC, getClosureActorIsolation)) {
1481
1490
case ActorIsolation::ActorInstance:
1482
1491
case ActorIsolation::Independent:
1483
1492
case ActorIsolation::Unspecified:
@@ -1560,6 +1569,9 @@ namespace {
1560
1569
SmallVector<ApplyExpr*, 4 > applyStack;
1561
1570
SmallVector<std::pair<OpaqueValueExpr *, Expr *>, 4 > opaqueValues;
1562
1571
SmallVector<const PatternBindingDecl *, 2 > patternBindingStack;
1572
+ llvm::function_ref<Type(Expr *)> getType;
1573
+ llvm::function_ref<ClosureActorIsolation(AbstractClosureExpr *)>
1574
+ getClosureActorIsolation;
1563
1575
1564
1576
// / Keeps track of the capture context of variables that have been
1565
1577
// / explicitly captured in closures.
@@ -1758,7 +1770,13 @@ namespace {
1758
1770
}
1759
1771
1760
1772
public:
1761
- ActorIsolationChecker (const DeclContext *dc) : ctx(dc->getASTContext ()) {
1773
+ ActorIsolationChecker (
1774
+ const DeclContext *dc,
1775
+ llvm::function_ref<Type(Expr *)> getType = __Expr_getType,
1776
+ llvm::function_ref<ClosureActorIsolation(AbstractClosureExpr *)>
1777
+ getClosureActorIsolation = __AbstractClosureExpr_getActorIsolation)
1778
+ : ctx(dc->getASTContext ()), getType(getType),
1779
+ getClosureActorIsolation(getClosureActorIsolation) {
1762
1780
contextStack.push_back (dc);
1763
1781
}
1764
1782
@@ -2058,7 +2076,7 @@ namespace {
2058
2076
break ;
2059
2077
2060
2078
if (auto closure = dyn_cast<AbstractClosureExpr>(dc)) {
2061
- auto isolation = closure-> getActorIsolation ( );
2079
+ auto isolation = getClosureActorIsolation (closure );
2062
2080
switch (isolation) {
2063
2081
case ClosureActorIsolation::Independent:
2064
2082
if (isSendableClosure (closure, /* forActorIsolation=*/ true )) {
@@ -2113,7 +2131,8 @@ namespace {
2113
2131
// Check isolation of the context itself. We do this separately
2114
2132
// from the closure check because closures capture specific variables
2115
2133
// while general isolation is declaration-based.
2116
- switch (auto isolation = getActorIsolationOfContext (dc)) {
2134
+ switch (auto isolation =
2135
+ getActorIsolationOfContext (dc, getClosureActorIsolation)) {
2117
2136
case ActorIsolation::Independent:
2118
2137
case ActorIsolation::Unspecified:
2119
2138
// Local functions can capture an isolated parameter.
@@ -2487,7 +2506,7 @@ namespace {
2487
2506
2488
2507
// / Check actor isolation for a particular application.
2489
2508
bool checkApply (ApplyExpr *apply) {
2490
- auto fnExprType = apply->getFn ()-> getType ( );
2509
+ auto fnExprType = getType ( apply->getFn ());
2491
2510
if (!fnExprType)
2492
2511
return false ;
2493
2512
@@ -2502,7 +2521,8 @@ namespace {
2502
2521
return *contextIsolation;
2503
2522
2504
2523
auto declContext = const_cast <DeclContext *>(getDeclContext ());
2505
- contextIsolation = getInnermostIsolatedContext (declContext);
2524
+ contextIsolation =
2525
+ getInnermostIsolatedContext (declContext, getClosureActorIsolation);
2506
2526
return *contextIsolation;
2507
2527
};
2508
2528
@@ -2539,9 +2559,9 @@ namespace {
2539
2559
// FIXME: The modeling of unsatisfiedIsolation is not great here.
2540
2560
// We'd be better off using something more like closure isolation
2541
2561
// that can talk about specific parameters.
2542
- auto nominal = arg-> getType ()->getAnyNominal ();
2562
+ auto nominal = getType (arg )->getAnyNominal ();
2543
2563
if (!nominal) {
2544
- nominal = arg-> getType ()->getASTContext ().getProtocol (
2564
+ nominal = getType (arg )->getASTContext ().getProtocol (
2545
2565
KnownProtocolKind::Actor);
2546
2566
}
2547
2567
@@ -2694,7 +2714,9 @@ namespace {
2694
2714
// Otherwise, we have concurrent access. Complain.
2695
2715
bool preconcurrencyContext =
2696
2716
getActorIsolationOfContext (
2697
- const_cast <DeclContext *>(getDeclContext ())).preconcurrency ();
2717
+ const_cast <DeclContext *>(getDeclContext ()),
2718
+ __AbstractClosureExpr_getActorIsolation)
2719
+ .preconcurrency ();
2698
2720
2699
2721
ctx.Diags .diagnose (
2700
2722
loc, diag::concurrent_access_of_local_capture,
@@ -2785,7 +2807,7 @@ namespace {
2785
2807
// where k is a captured dictionary key.
2786
2808
if (auto *args = component.getSubscriptArgs ()) {
2787
2809
for (auto arg : *args) {
2788
- auto type = arg.getExpr ()-> getType ( );
2810
+ auto type = getType ( arg.getExpr ());
2789
2811
if (type &&
2790
2812
shouldDiagnoseExistingDataRaces (getDeclContext ()) &&
2791
2813
diagnoseNonSendableTypes (
@@ -2818,8 +2840,8 @@ namespace {
2818
2840
if (base)
2819
2841
isolatedActor.emplace (getIsolatedActor (base));
2820
2842
auto result = ActorReferenceResult::forReference (
2821
- declRef, loc, getDeclContext (),
2822
- kindOfUsage (decl, context), isolatedActor );
2843
+ declRef, loc, getDeclContext (), kindOfUsage (decl, context),
2844
+ isolatedActor, None, None, getClosureActorIsolation );
2823
2845
switch (result) {
2824
2846
case ActorReferenceResult::SameConcurrencyDomain:
2825
2847
if (diagnoseReferenceToUnsafeGlobal (decl, loc))
@@ -2903,7 +2925,8 @@ namespace {
2903
2925
refKind = isolatedActor->kind ;
2904
2926
refGlobalActor = isolatedActor->globalActor ;
2905
2927
} else {
2906
- auto contextIsolation = getInnermostIsolatedContext (getDeclContext ());
2928
+ auto contextIsolation = getInnermostIsolatedContext (
2929
+ getDeclContext (), getClosureActorIsolation);
2907
2930
switch (contextIsolation) {
2908
2931
case ActorIsolation::ActorInstance:
2909
2932
refKind = ReferencedActor::Isolated;
@@ -2952,7 +2975,7 @@ namespace {
2952
2975
// Attempt to resolve the global actor type of a closure.
2953
2976
Type resolveGlobalActorType (ClosureExpr *closure) {
2954
2977
// Check whether the closure's type has a global actor already.
2955
- if (Type closureType = closure-> getType ()) {
2978
+ if (Type closureType = getType (closure )) {
2956
2979
if (auto closureFnType = closureType->getAs <FunctionType>()) {
2957
2980
if (Type globalActor = closureFnType->getGlobalActor ())
2958
2981
return globalActor;
@@ -2994,7 +3017,8 @@ namespace {
2994
3017
return ClosureActorIsolation::forIndependent (preconcurrency);
2995
3018
2996
3019
// A non-Sendable closure gets its isolation from its context.
2997
- auto parentIsolation = getActorIsolationOfContext (closure->getParent ());
3020
+ auto parentIsolation = getActorIsolationOfContext (
3021
+ closure->getParent (), getClosureActorIsolation);
2998
3022
preconcurrency |= parentIsolation.preconcurrency ();
2999
3023
3000
3024
// We must have parent isolation determined to get here.
@@ -3032,10 +3056,10 @@ bool ActorIsolationChecker::mayExecuteConcurrentlyWith(
3032
3056
// If both contexts are isolated to the same actor, then they will not
3033
3057
// execute concurrently.
3034
3058
auto useIsolation = getActorIsolationOfContext (
3035
- const_cast <DeclContext *>(useContext));
3059
+ const_cast <DeclContext *>(useContext), getClosureActorIsolation );
3036
3060
if (useIsolation.isActorIsolated ()) {
3037
3061
auto defIsolation = getActorIsolationOfContext (
3038
- const_cast <DeclContext *>(defContext));
3062
+ const_cast <DeclContext *>(defContext), getClosureActorIsolation );
3039
3063
if (useIsolation == defIsolation)
3040
3064
return false ;
3041
3065
}
@@ -3109,9 +3133,12 @@ void swift::checkPropertyWrapperActorIsolation(
3109
3133
expr->walk (checker);
3110
3134
}
3111
3135
3112
- ClosureActorIsolation
3113
- swift::determineClosureActorIsolation (AbstractClosureExpr *closure) {
3114
- ActorIsolationChecker checker (closure->getParent ());
3136
+ ClosureActorIsolation swift::determineClosureActorIsolation (
3137
+ AbstractClosureExpr *closure, llvm::function_ref<Type(Expr *)> getType,
3138
+ llvm::function_ref<ClosureActorIsolation(AbstractClosureExpr *)>
3139
+ getClosureActorIsolation) {
3140
+ ActorIsolationChecker checker (closure->getParent (), getType,
3141
+ getClosureActorIsolation);
3115
3142
return checker.determineClosureIsolation (closure);
3116
3143
}
3117
3144
@@ -3801,14 +3828,15 @@ ActorIsolation ActorIsolationRequest::evaluate(
3801
3828
// If this is a defer body, inherit unconditionally; we don't
3802
3829
// care if the enclosing function captures the isolated parameter.
3803
3830
if (func->isDeferBody ()) {
3804
- auto enclosingIsolation =
3805
- getActorIsolationOfContext ( func->getDeclContext ());
3831
+ auto enclosingIsolation = getActorIsolationOfContext (
3832
+ func->getDeclContext (), __AbstractClosureExpr_getActorIsolation );
3806
3833
return inferredIsolation (enclosingIsolation);
3807
3834
}
3808
3835
3809
3836
if (func->isLocalCapture () && !func->isSendable ()) {
3810
- switch (auto enclosingIsolation =
3811
- getActorIsolationOfContext (func->getDeclContext ())) {
3837
+ switch (auto enclosingIsolation = getActorIsolationOfContext (
3838
+ func->getDeclContext (),
3839
+ __AbstractClosureExpr_getActorIsolation)) {
3812
3840
case ActorIsolation::Independent:
3813
3841
case ActorIsolation::Unspecified:
3814
3842
// Do nothing.
@@ -5092,10 +5120,11 @@ static bool equivalentIsolationContexts(
5092
5120
5093
5121
ActorReferenceResult ActorReferenceResult::forReference (
5094
5122
ConcreteDeclRef declRef, SourceLoc declRefLoc, const DeclContext *fromDC,
5095
- Optional<VarRefUseEnv> useKind,
5096
- Optional<ReferencedActor> actorInstance,
5123
+ Optional<VarRefUseEnv> useKind, Optional<ReferencedActor> actorInstance,
5097
5124
Optional<ActorIsolation> knownDeclIsolation,
5098
- Optional<ActorIsolation> knownContextIsolation) {
5125
+ Optional<ActorIsolation> knownContextIsolation,
5126
+ llvm::function_ref<ClosureActorIsolation(AbstractClosureExpr *)>
5127
+ getClosureActorIsolation) {
5099
5128
// If not provided, compute the isolation of the declaration, adjusted
5100
5129
// for references.
5101
5130
ActorIsolation declIsolation = ActorIsolation::forUnspecified ();
@@ -5117,7 +5146,8 @@ ActorReferenceResult ActorReferenceResult::forReference(
5117
5146
if (knownContextIsolation) {
5118
5147
contextIsolation = *knownContextIsolation;
5119
5148
} else {
5120
- contextIsolation = getInnermostIsolatedContext (fromDC);
5149
+ contextIsolation =
5150
+ getInnermostIsolatedContext (fromDC, getClosureActorIsolation);
5121
5151
}
5122
5152
5123
5153
// When the declaration is not actor-isolated, it can always be accessed
0 commit comments