@@ -136,7 +136,7 @@ bool swift::usesFlowSensitiveIsolation(AbstractFunctionDecl const *fn) {
136
136
return true ;
137
137
138
138
// construct an isolation corresponding to the type.
139
- auto actorTypeIso = ActorIsolation::forActorInstance (nominal);
139
+ auto actorTypeIso = ActorIsolation::forActorInstanceSelf (nominal);
140
140
141
141
return requiresFlowIsolation (actorTypeIso, cast<ConstructorDecl>(fn));
142
142
}
@@ -2521,7 +2521,6 @@ namespace {
2521
2521
return false ;
2522
2522
2523
2523
// Check for isolated parameters.
2524
- Optional<unsigned > isolatedParamIdx;
2525
2524
for (unsigned paramIdx : range (fnType->getNumParams ())) {
2526
2525
// We only care about isolated parameters.
2527
2526
if (!fnType->getParams ()[paramIdx].isIsolated ())
@@ -2545,8 +2544,8 @@ namespace {
2545
2544
KnownProtocolKind::Actor);
2546
2545
}
2547
2546
2548
- unsatisfiedIsolation = ActorIsolation::forActorInstance (nominal);
2549
- isolatedParamIdx = paramIdx;
2547
+ unsatisfiedIsolation =
2548
+ ActorIsolation::forActorInstanceParameter (nominal, paramIdx) ;
2550
2549
break ;
2551
2550
}
2552
2551
@@ -2595,7 +2594,8 @@ namespace {
2595
2594
2596
2595
case ActorIsolation::ActorInstance:
2597
2596
apply->setImplicitlyAsync (
2598
- ImplicitActorHopTarget::forIsolatedParameter (*isolatedParamIdx));
2597
+ ImplicitActorHopTarget::forIsolatedParameter (
2598
+ unsatisfiedIsolation->getActorInstanceParameter () - 1 ));
2599
2599
break ;
2600
2600
2601
2601
case ActorIsolation::Unspecified:
@@ -2847,8 +2847,12 @@ namespace {
2847
2847
if (partialApply && result.isolation .isGlobalActor ())
2848
2848
return false ;
2849
2849
2850
- // A call to a global-actor-isolated function is diagnosed elsewhere.
2851
- if (!partialApply && result.isolation .isGlobalActor () &&
2850
+ // A call to a global-actor-isolated function, or a function with an
2851
+ // isolated parameter, is diagnosed elsewhere.
2852
+ if (!partialApply &&
2853
+ (result.isolation .isGlobalActor () ||
2854
+ (result.isolation == ActorIsolation::ActorInstance &&
2855
+ result.isolation .getActorInstanceParameter () > 0 )) &&
2852
2856
isa<AbstractFunctionDecl>(decl))
2853
2857
return false ;
2854
2858
@@ -3654,14 +3658,45 @@ static OverrideIsolationResult validOverrideIsolation(
3654
3658
}
3655
3659
}
3656
3660
3661
+ // / Retrieve the index of the first isolated parameter of the given
3662
+ // / declaration, if there is one.
3663
+ static Optional<unsigned > getIsolatedParamIndex (ValueDecl *value) {
3664
+ auto params = getParameterList (value);
3665
+ if (!params)
3666
+ return None;
3667
+
3668
+ for (unsigned paramIdx : range (params->size ())) {
3669
+ auto param = params->get (paramIdx);
3670
+ if (param->isIsolated ())
3671
+ return paramIdx;
3672
+ }
3673
+
3674
+ return None;
3675
+ }
3676
+
3657
3677
ActorIsolation ActorIsolationRequest::evaluate (
3658
3678
Evaluator &evaluator, ValueDecl *value) const {
3659
3679
// If this declaration has actor-isolated "self", it's isolated to that
3660
3680
// actor.
3661
3681
if (evaluateOrDefault (evaluator, HasIsolatedSelfRequest{value}, false )) {
3662
3682
auto actor = value->getDeclContext ()->getSelfNominalTypeDecl ();
3663
3683
assert (actor && " could not find the actor that 'self' is isolated to" );
3664
- return ActorIsolation::forActorInstance (actor);
3684
+ return ActorIsolation::forActorInstanceSelf (actor);
3685
+ }
3686
+
3687
+ // If this declaration has an isolated parameter, it's isolated to that
3688
+ // parameter.
3689
+ if (auto paramIdx = getIsolatedParamIndex (value)) {
3690
+ // FIXME: This doesn't allow us to find an Actor or DistributedActor
3691
+ // bound on the parameter type effectively.
3692
+ auto param = getParameterList (value)->get (*paramIdx);
3693
+ Type paramType = param->getInterfaceType ();
3694
+ if (paramType->isTypeParameter ()) {
3695
+ paramType = param->getDeclContext ()->mapTypeIntoContext (paramType);
3696
+ }
3697
+
3698
+ if (auto actor = paramType->getAnyActor ())
3699
+ return ActorIsolation::forActorInstanceParameter (actor, *paramIdx);
3665
3700
}
3666
3701
3667
3702
auto isolationFromAttr = getIsolationFromAttributes (value);
@@ -3947,6 +3982,10 @@ bool HasIsolatedSelfRequest::evaluate(
3947
3982
value = accessor->getStorage ();
3948
3983
}
3949
3984
3985
+ // If there is an isolated parameter, then "self" is not isolated.
3986
+ if (getIsolatedParamIndex (value))
3987
+ return false ;
3988
+
3950
3989
// Check whether this member can be isolated to an actor at all.
3951
3990
auto memberIsolation = getMemberIsolationPropagation (value);
3952
3991
if (!memberIsolation)
@@ -4950,7 +4989,7 @@ static ActorIsolation getActorIsolationForReference(
4950
4989
// as needing to enter the actor.
4951
4990
if (auto nominal = ctor->getDeclContext ()->getSelfNominalTypeDecl ()) {
4952
4991
if (nominal->isAnyActor ())
4953
- return ActorIsolation::forActorInstance (nominal);
4992
+ return ActorIsolation::forActorInstanceSelf (nominal);
4954
4993
}
4955
4994
4956
4995
// Fall through to treat initializers like any other declaration.
@@ -4966,7 +5005,7 @@ static ActorIsolation getActorIsolationForReference(
4966
5005
declIsolation.isIndependent ()) {
4967
5006
if (auto nominal = var->getDeclContext ()->getSelfNominalTypeDecl ()) {
4968
5007
if (nominal->isAnyActor ())
4969
- return ActorIsolation::forActorInstance (nominal);
5008
+ return ActorIsolation::forActorInstanceSelf (nominal);
4970
5009
4971
5010
auto nominalIsolation = getActorIsolation (nominal);
4972
5011
if (nominalIsolation.isGlobalActor ())
@@ -5137,7 +5176,8 @@ ActorReferenceResult ActorReferenceResult::forReference(
5137
5176
5138
5177
// The declaration we are accessing is actor-isolated. First, check whether
5139
5178
// we are on the same actor already.
5140
- if (actorInstance && declIsolation == ActorIsolation::ActorInstance) {
5179
+ if (actorInstance && declIsolation == ActorIsolation::ActorInstance &&
5180
+ declIsolation.getActorInstanceParameter () == 0 ) {
5141
5181
// If this instance is isolated, we're in the same concurrency domain.
5142
5182
if (actorInstance->isIsolated ())
5143
5183
return forSameConcurrencyDomain (declIsolation);
0 commit comments