@@ -3143,7 +3143,10 @@ namespace {
3143
3143
if (!unsatisfiedIsolation)
3144
3144
return false ;
3145
3145
3146
- if (refineRequiredIsolation (*unsatisfiedIsolation))
3146
+ bool onlyArgsCrossIsolation = callOptions.contains (
3147
+ ActorReferenceResult::Flags::OnlyArgsCrossIsolation);
3148
+ if (!onlyArgsCrossIsolation &&
3149
+ refineRequiredIsolation (*unsatisfiedIsolation))
3147
3150
return false ;
3148
3151
3149
3152
// At this point, we know a jump is made to the callee that yields
@@ -4757,14 +4760,19 @@ DefaultInitializerIsolation::evaluate(Evaluator &evaluator,
4757
4760
4758
4761
Initializer *dc = nullptr ;
4759
4762
Expr *initExpr = nullptr ;
4763
+ ActorIsolation enclosingIsolation;
4760
4764
4761
4765
if (auto *pbd = var->getParentPatternBinding ()) {
4762
4766
if (!var->isParentInitialized ())
4763
4767
return ActorIsolation::forUnspecified ();
4764
4768
4765
4769
auto i = pbd->getPatternEntryIndexForVarDecl (var);
4770
+ if (!pbd->isInitializerChecked (i))
4771
+ TypeChecker::typeCheckPatternBinding (pbd, i);
4772
+
4766
4773
dc = cast<Initializer>(pbd->getInitContext (i));
4767
- initExpr = var->getParentInitializer ();
4774
+ initExpr = pbd->getInit (i);
4775
+ enclosingIsolation = getActorIsolation (var);
4768
4776
} else if (auto *param = dyn_cast<ParamDecl>(var)) {
4769
4777
// If this parameter corresponds to a stored property for a
4770
4778
// memberwise initializer, the default argument is the default
@@ -4782,13 +4790,27 @@ DefaultInitializerIsolation::evaluate(Evaluator &evaluator,
4782
4790
4783
4791
dc = param->getDefaultArgumentInitContext ();
4784
4792
initExpr = param->getTypeCheckedDefaultExpr ();
4793
+ enclosingIsolation =
4794
+ getActorIsolationOfContext (param->getDeclContext ());
4785
4795
}
4786
4796
4787
4797
if (!dc || !initExpr)
4788
4798
return ActorIsolation::forUnspecified ();
4789
4799
4800
+ // If the default argument has isolation, it must match the
4801
+ // isolation of the decl context.
4790
4802
ActorIsolationChecker checker (dc);
4791
- return checker.computeRequiredIsolation (initExpr);
4803
+ auto requiredIsolation = checker.computeRequiredIsolation (initExpr);
4804
+ if (requiredIsolation.isActorIsolated ()) {
4805
+ if (enclosingIsolation != requiredIsolation) {
4806
+ var->diagnose (
4807
+ diag::isolated_default_argument_context,
4808
+ requiredIsolation, enclosingIsolation);
4809
+ return ActorIsolation::forUnspecified ();
4810
+ }
4811
+ }
4812
+
4813
+ return requiredIsolation;
4792
4814
}
4793
4815
4794
4816
void swift::checkOverrideActorIsolation (ValueDecl *value) {
@@ -5859,8 +5881,8 @@ bool swift::isAccessibleAcrossActors(
5859
5881
}
5860
5882
5861
5883
ActorReferenceResult ActorReferenceResult::forSameConcurrencyDomain (
5862
- ActorIsolation isolation) {
5863
- return ActorReferenceResult{SameConcurrencyDomain, llvm::None , isolation};
5884
+ ActorIsolation isolation, Options options ) {
5885
+ return ActorReferenceResult{SameConcurrencyDomain, options , isolation};
5864
5886
}
5865
5887
5866
5888
ActorReferenceResult ActorReferenceResult::forEntersActor (
@@ -5869,8 +5891,8 @@ ActorReferenceResult ActorReferenceResult::forEntersActor(
5869
5891
}
5870
5892
5871
5893
ActorReferenceResult ActorReferenceResult::forExitsActorToNonisolated (
5872
- ActorIsolation isolation) {
5873
- return ActorReferenceResult{ExitsActorToNonisolated, llvm::None , isolation};
5894
+ ActorIsolation isolation, Options options ) {
5895
+ return ActorReferenceResult{ExitsActorToNonisolated, options , isolation};
5874
5896
}
5875
5897
5876
5898
// Determine if two actor isolation contexts are considered to be equivalent.
@@ -5906,10 +5928,24 @@ ActorReferenceResult ActorReferenceResult::forReference(
5906
5928
declIsolation = declIsolation.subst (declRef.getSubstitutions ());
5907
5929
}
5908
5930
5931
+ // Determine what adjustments we need to perform for cross-actor
5932
+ // references.
5933
+ Options options = llvm::None;
5934
+
5935
+ // FIXME: Actor constructors are modeled as isolated to the actor
5936
+ // so that Sendable checking is applied to their arguments, but the
5937
+ // call itself does not hop to another executor.
5938
+ if (auto ctor = dyn_cast<ConstructorDecl>(declRef.getDecl ())) {
5939
+ if (auto nominal = ctor->getDeclContext ()->getSelfNominalTypeDecl ()) {
5940
+ if (nominal->isAnyActor ())
5941
+ options |= Flags::OnlyArgsCrossIsolation;
5942
+ }
5943
+ }
5944
+
5909
5945
// If the entity we are referencing is not a value, we're in the same
5910
5946
// concurrency domain.
5911
5947
if (isNonValueReference (declRef.getDecl ()))
5912
- return forSameConcurrencyDomain (declIsolation);
5948
+ return forSameConcurrencyDomain (declIsolation, options );
5913
5949
5914
5950
// Compute the isolation of the context, if not provided.
5915
5951
ActorIsolation contextIsolation = ActorIsolation::forUnspecified ();
@@ -5928,11 +5964,11 @@ ActorReferenceResult ActorReferenceResult::forReference(
5928
5964
if (isAsyncDecl (declRef) && contextIsolation.isActorIsolated () &&
5929
5965
!declRef.getDecl ()->getAttrs ()
5930
5966
.hasAttribute <UnsafeInheritExecutorAttr>())
5931
- return forExitsActorToNonisolated (contextIsolation);
5967
+ return forExitsActorToNonisolated (contextIsolation, options );
5932
5968
5933
5969
// Otherwise, we stay in the same concurrency domain, whether on an actor
5934
5970
// or in a task.
5935
- return forSameConcurrencyDomain (declIsolation);
5971
+ return forSameConcurrencyDomain (declIsolation, options );
5936
5972
}
5937
5973
5938
5974
// The declaration we are accessing is actor-isolated. First, check whether
@@ -5941,11 +5977,11 @@ ActorReferenceResult ActorReferenceResult::forReference(
5941
5977
declIsolation.getActorInstanceParameter () == 0 ) {
5942
5978
// If this instance is isolated, we're in the same concurrency domain.
5943
5979
if (actorInstance->isIsolated ())
5944
- return forSameConcurrencyDomain (declIsolation);
5980
+ return forSameConcurrencyDomain (declIsolation, options );
5945
5981
} else if (equivalentIsolationContexts (declIsolation, contextIsolation)) {
5946
5982
// The context isolation matches, so we are in the same concurrency
5947
5983
// domain.
5948
- return forSameConcurrencyDomain (declIsolation);
5984
+ return forSameConcurrencyDomain (declIsolation, options );
5949
5985
}
5950
5986
5951
5987
// Initializing an actor isolated stored property with a value effectively
@@ -5965,7 +6001,8 @@ ActorReferenceResult ActorReferenceResult::forReference(
5965
6001
// Treat the decl isolation as 'preconcurrency' to downgrade violations
5966
6002
// to warnings, because violating Sendable here is accepted by the
5967
6003
// Swift 5.9 compiler.
5968
- return forEntersActor (declIsolation, Flags::Preconcurrency);
6004
+ options |= Flags::Preconcurrency;
6005
+ return forEntersActor (declIsolation, options);
5969
6006
}
5970
6007
}
5971
6008
}
@@ -5975,7 +6012,7 @@ ActorReferenceResult ActorReferenceResult::forReference(
5975
6012
if (actorInstance &&
5976
6013
checkedByFlowIsolation (
5977
6014
fromDC, *actorInstance, declRef.getDecl (), declRefLoc, useKind))
5978
- return forSameConcurrencyDomain (declIsolation);
6015
+ return forSameConcurrencyDomain (declIsolation, options );
5979
6016
5980
6017
// If we are delegating to another initializer, treat them as being in the
5981
6018
// same concurrency domain.
@@ -5984,7 +6021,7 @@ ActorReferenceResult ActorReferenceResult::forReference(
5984
6021
if (actorInstance && actorInstance->isSelf () &&
5985
6022
isa<ConstructorDecl>(declRef.getDecl ()) &&
5986
6023
isa<ConstructorDecl>(fromDC))
5987
- return forSameConcurrencyDomain (declIsolation);
6024
+ return forSameConcurrencyDomain (declIsolation, options );
5988
6025
5989
6026
// If there is an instance that corresponds to 'self',
5990
6027
// we are in a constructor or destructor, and we have a stored property of
@@ -5994,18 +6031,14 @@ ActorReferenceResult ActorReferenceResult::forReference(
5994
6031
isNonInheritedStorage (declRef.getDecl (), fromDC) &&
5995
6032
declIsolation.isGlobalActor () &&
5996
6033
(isa<ConstructorDecl>(fromDC) || isa<DestructorDecl>(fromDC)))
5997
- return forSameConcurrencyDomain (declIsolation);
5998
-
5999
- // Determine what adjustments we need to perform for cross-actor
6000
- // references.
6001
- Options options = llvm::None;
6034
+ return forSameConcurrencyDomain (declIsolation, options);
6002
6035
6003
6036
// At this point, we are accessing the target from outside the actor.
6004
6037
// First, check whether it is something that can be accessed directly,
6005
6038
// without any kind of promotion.
6006
6039
if (isAccessibleAcrossActors (
6007
6040
declRef.getDecl (), declIsolation, fromDC, options, actorInstance))
6008
- return forEntersActor (declIsolation, llvm::None );
6041
+ return forEntersActor (declIsolation, options );
6009
6042
6010
6043
// This is a cross-actor reference.
6011
6044
0 commit comments