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) {
@@ -1450,10 +1455,14 @@ static bool checkedByFlowIsolation(DeclContext const *refCxt,
1450
1455
}
1451
1456
1452
1457
// / Get the actor isolation of the innermost relevant context.
1453
- static ActorIsolation getInnermostIsolatedContext (const DeclContext *dc) {
1458
+ static ActorIsolation getInnermostIsolatedContext (
1459
+ const DeclContext *dc,
1460
+ llvm::function_ref<ClosureActorIsolation(AbstractClosureExpr *)>
1461
+ getClosureActorIsolation) {
1454
1462
// Retrieve the actor isolation of the context.
1455
1463
auto mutableDC = const_cast <DeclContext *>(dc);
1456
- switch (auto isolation = getActorIsolationOfContext (mutableDC)) {
1464
+ switch (auto isolation =
1465
+ getActorIsolationOfContext (mutableDC, getClosureActorIsolation)) {
1457
1466
case ActorIsolation::ActorInstance:
1458
1467
case ActorIsolation::Independent:
1459
1468
case ActorIsolation::Unspecified:
@@ -1536,6 +1545,9 @@ namespace {
1536
1545
SmallVector<ApplyExpr*, 4 > applyStack;
1537
1546
SmallVector<std::pair<OpaqueValueExpr *, Expr *>, 4 > opaqueValues;
1538
1547
SmallVector<const PatternBindingDecl *, 2 > patternBindingStack;
1548
+ llvm::function_ref<Type(Expr *)> getType;
1549
+ llvm::function_ref<ClosureActorIsolation(AbstractClosureExpr *)>
1550
+ getClosureActorIsolation;
1539
1551
1540
1552
// / Keeps track of the capture context of variables that have been
1541
1553
// / explicitly captured in closures.
@@ -1734,7 +1746,13 @@ namespace {
1734
1746
}
1735
1747
1736
1748
public:
1737
- ActorIsolationChecker (const DeclContext *dc) : ctx(dc->getASTContext ()) {
1749
+ ActorIsolationChecker (
1750
+ const DeclContext *dc,
1751
+ llvm::function_ref<Type(Expr *)> getType = __Expr_getType,
1752
+ llvm::function_ref<ClosureActorIsolation(AbstractClosureExpr *)>
1753
+ getClosureActorIsolation = __AbstractClosureExpr_getActorIsolation)
1754
+ : ctx(dc->getASTContext ()), getType(getType),
1755
+ getClosureActorIsolation(getClosureActorIsolation) {
1738
1756
contextStack.push_back (dc);
1739
1757
}
1740
1758
@@ -2034,7 +2052,7 @@ namespace {
2034
2052
break ;
2035
2053
2036
2054
if (auto closure = dyn_cast<AbstractClosureExpr>(dc)) {
2037
- auto isolation = closure-> getActorIsolation ( );
2055
+ auto isolation = getClosureActorIsolation (closure );
2038
2056
switch (isolation) {
2039
2057
case ClosureActorIsolation::Independent:
2040
2058
if (isSendableClosure (closure, /* forActorIsolation=*/ true )) {
@@ -2089,7 +2107,8 @@ namespace {
2089
2107
// Check isolation of the context itself. We do this separately
2090
2108
// from the closure check because closures capture specific variables
2091
2109
// while general isolation is declaration-based.
2092
- switch (auto isolation = getActorIsolationOfContext (dc)) {
2110
+ switch (auto isolation =
2111
+ getActorIsolationOfContext (dc, getClosureActorIsolation)) {
2093
2112
case ActorIsolation::Independent:
2094
2113
case ActorIsolation::Unspecified:
2095
2114
// Local functions can capture an isolated parameter.
@@ -2459,7 +2478,7 @@ namespace {
2459
2478
2460
2479
// / Check actor isolation for a particular application.
2461
2480
bool checkApply (ApplyExpr *apply) {
2462
- auto fnExprType = apply->getFn ()-> getType ( );
2481
+ auto fnExprType = getType ( apply->getFn ());
2463
2482
if (!fnExprType)
2464
2483
return false ;
2465
2484
@@ -2474,7 +2493,8 @@ namespace {
2474
2493
return *contextIsolation;
2475
2494
2476
2495
auto declContext = const_cast <DeclContext *>(getDeclContext ());
2477
- contextIsolation = getInnermostIsolatedContext (declContext);
2496
+ contextIsolation =
2497
+ getInnermostIsolatedContext (declContext, getClosureActorIsolation);
2478
2498
return *contextIsolation;
2479
2499
};
2480
2500
@@ -2511,9 +2531,9 @@ namespace {
2511
2531
// FIXME: The modeling of unsatisfiedIsolation is not great here.
2512
2532
// We'd be better off using something more like closure isolation
2513
2533
// that can talk about specific parameters.
2514
- auto nominal = arg-> getType ()->getAnyNominal ();
2534
+ auto nominal = getType (arg )->getAnyNominal ();
2515
2535
if (!nominal) {
2516
- nominal = arg-> getType ()->getASTContext ().getProtocol (
2536
+ nominal = getType (arg )->getASTContext ().getProtocol (
2517
2537
KnownProtocolKind::Actor);
2518
2538
}
2519
2539
@@ -2751,7 +2771,7 @@ namespace {
2751
2771
// where k is a captured dictionary key.
2752
2772
if (auto *args = component.getSubscriptArgs ()) {
2753
2773
for (auto arg : *args) {
2754
- auto type = arg.getExpr ()-> getType ( );
2774
+ auto type = getType ( arg.getExpr ());
2755
2775
if (type &&
2756
2776
shouldDiagnoseExistingDataRaces (getDeclContext ()) &&
2757
2777
diagnoseNonSendableTypes (
@@ -2784,8 +2804,8 @@ namespace {
2784
2804
if (base)
2785
2805
isolatedActor.emplace (getIsolatedActor (base));
2786
2806
auto result = ActorReferenceResult::forReference (
2787
- declRef, loc, getDeclContext (),
2788
- kindOfUsage (decl, context), isolatedActor );
2807
+ declRef, loc, getDeclContext (), kindOfUsage (decl, context),
2808
+ isolatedActor, None, None, getClosureActorIsolation );
2789
2809
switch (result) {
2790
2810
case ActorReferenceResult::SameConcurrencyDomain:
2791
2811
if (diagnoseReferenceToUnsafeGlobal (decl, loc))
@@ -2869,7 +2889,8 @@ namespace {
2869
2889
refKind = isolatedActor->kind ;
2870
2890
refGlobalActor = isolatedActor->globalActor ;
2871
2891
} else {
2872
- auto contextIsolation = getInnermostIsolatedContext (getDeclContext ());
2892
+ auto contextIsolation = getInnermostIsolatedContext (
2893
+ getDeclContext (), getClosureActorIsolation);
2873
2894
switch (contextIsolation) {
2874
2895
case ActorIsolation::ActorInstance:
2875
2896
refKind = ReferencedActor::Isolated;
@@ -2913,7 +2934,7 @@ namespace {
2913
2934
// Attempt to resolve the global actor type of a closure.
2914
2935
Type resolveGlobalActorType (ClosureExpr *closure) {
2915
2936
// Check whether the closure's type has a global actor already.
2916
- if (Type closureType = closure-> getType ()) {
2937
+ if (Type closureType = getType (closure )) {
2917
2938
if (auto closureFnType = closureType->getAs <FunctionType>()) {
2918
2939
if (Type globalActor = closureFnType->getGlobalActor ())
2919
2940
return globalActor;
@@ -2955,7 +2976,8 @@ namespace {
2955
2976
return ClosureActorIsolation::forIndependent (preconcurrency);
2956
2977
2957
2978
// A non-Sendable closure gets its isolation from its context.
2958
- auto parentIsolation = getActorIsolationOfContext (closure->getParent ());
2979
+ auto parentIsolation = getActorIsolationOfContext (
2980
+ closure->getParent (), getClosureActorIsolation);
2959
2981
preconcurrency |= parentIsolation.preconcurrency ();
2960
2982
2961
2983
// We must have parent isolation determined to get here.
@@ -2993,10 +3015,10 @@ bool ActorIsolationChecker::mayExecuteConcurrentlyWith(
2993
3015
// If both contexts are isolated to the same actor, then they will not
2994
3016
// execute concurrently.
2995
3017
auto useIsolation = getActorIsolationOfContext (
2996
- const_cast <DeclContext *>(useContext));
3018
+ const_cast <DeclContext *>(useContext), getClosureActorIsolation );
2997
3019
if (useIsolation.isActorIsolated ()) {
2998
3020
auto defIsolation = getActorIsolationOfContext (
2999
- const_cast <DeclContext *>(defContext));
3021
+ const_cast <DeclContext *>(defContext), getClosureActorIsolation );
3000
3022
if (useIsolation == defIsolation)
3001
3023
return false ;
3002
3024
}
@@ -3070,9 +3092,12 @@ void swift::checkPropertyWrapperActorIsolation(
3070
3092
expr->walk (checker);
3071
3093
}
3072
3094
3073
- ClosureActorIsolation
3074
- swift::determineClosureActorIsolation (AbstractClosureExpr *closure) {
3075
- ActorIsolationChecker checker (closure->getParent ());
3095
+ ClosureActorIsolation swift::determineClosureActorIsolation (
3096
+ AbstractClosureExpr *closure, llvm::function_ref<Type(Expr *)> getType,
3097
+ llvm::function_ref<ClosureActorIsolation(AbstractClosureExpr *)>
3098
+ getClosureActorIsolation) {
3099
+ ActorIsolationChecker checker (closure->getParent (), getType,
3100
+ getClosureActorIsolation);
3076
3101
return checker.determineClosureIsolation (closure);
3077
3102
}
3078
3103
@@ -3762,14 +3787,15 @@ ActorIsolation ActorIsolationRequest::evaluate(
3762
3787
// If this is a defer body, inherit unconditionally; we don't
3763
3788
// care if the enclosing function captures the isolated parameter.
3764
3789
if (func->isDeferBody ()) {
3765
- auto enclosingIsolation =
3766
- getActorIsolationOfContext ( func->getDeclContext ());
3790
+ auto enclosingIsolation = getActorIsolationOfContext (
3791
+ func->getDeclContext (), __AbstractClosureExpr_getActorIsolation );
3767
3792
return inferredIsolation (enclosingIsolation);
3768
3793
}
3769
3794
3770
3795
if (func->isLocalCapture () && !func->isSendable ()) {
3771
- switch (auto enclosingIsolation =
3772
- getActorIsolationOfContext (func->getDeclContext ())) {
3796
+ switch (auto enclosingIsolation = getActorIsolationOfContext (
3797
+ func->getDeclContext (),
3798
+ __AbstractClosureExpr_getActorIsolation)) {
3773
3799
case ActorIsolation::Independent:
3774
3800
case ActorIsolation::Unspecified:
3775
3801
// Do nothing.
@@ -5020,10 +5046,11 @@ static bool equivalentIsolationContexts(
5020
5046
5021
5047
ActorReferenceResult ActorReferenceResult::forReference (
5022
5048
ConcreteDeclRef declRef, SourceLoc declRefLoc, const DeclContext *fromDC,
5023
- Optional<VarRefUseEnv> useKind,
5024
- Optional<ReferencedActor> actorInstance,
5049
+ Optional<VarRefUseEnv> useKind, Optional<ReferencedActor> actorInstance,
5025
5050
Optional<ActorIsolation> knownDeclIsolation,
5026
- Optional<ActorIsolation> knownContextIsolation) {
5051
+ Optional<ActorIsolation> knownContextIsolation,
5052
+ llvm::function_ref<ClosureActorIsolation(AbstractClosureExpr *)>
5053
+ getClosureActorIsolation) {
5027
5054
// If not provided, compute the isolation of the declaration, adjusted
5028
5055
// for references.
5029
5056
ActorIsolation declIsolation = ActorIsolation::forUnspecified ();
@@ -5045,7 +5072,8 @@ ActorReferenceResult ActorReferenceResult::forReference(
5045
5072
if (knownContextIsolation) {
5046
5073
contextIsolation = *knownContextIsolation;
5047
5074
} else {
5048
- contextIsolation = getInnermostIsolatedContext (fromDC);
5075
+ contextIsolation =
5076
+ getInnermostIsolatedContext (fromDC, getClosureActorIsolation);
5049
5077
}
5050
5078
5051
5079
// When the declaration is not actor-isolated, it can always be accessed
0 commit comments