@@ -3188,7 +3188,10 @@ namespace {
31883188 if (!unsatisfiedIsolation)
31893189 return false ;
31903190
3191- if (refineRequiredIsolation (*unsatisfiedIsolation))
3191+ bool onlyArgsCrossIsolation = callOptions.contains (
3192+ ActorReferenceResult::Flags::OnlyArgsCrossIsolation);
3193+ if (!onlyArgsCrossIsolation &&
3194+ refineRequiredIsolation (*unsatisfiedIsolation))
31923195 return false ;
31933196
31943197 // At this point, we know a jump is made to the callee that yields
@@ -4808,6 +4811,7 @@ DefaultInitializerIsolation::evaluate(Evaluator &evaluator,
48084811
48094812 Initializer *dc = nullptr ;
48104813 Expr *initExpr = nullptr ;
4814+ ActorIsolation enclosingIsolation;
48114815
48124816 if (auto *pbd = var->getParentPatternBinding ()) {
48134817 if (!var->isParentInitialized ())
@@ -4816,6 +4820,7 @@ DefaultInitializerIsolation::evaluate(Evaluator &evaluator,
48164820 auto i = pbd->getPatternEntryIndexForVarDecl (var);
48174821 dc = cast<Initializer>(pbd->getInitContext (i));
48184822 initExpr = var->getParentInitializer ();
4823+ enclosingIsolation = getActorIsolation (var);
48194824 } else if (auto *param = dyn_cast<ParamDecl>(var)) {
48204825 // If this parameter corresponds to a stored property for a
48214826 // memberwise initializer, the default argument is the default
@@ -4833,13 +4838,27 @@ DefaultInitializerIsolation::evaluate(Evaluator &evaluator,
48334838
48344839 dc = param->getDefaultArgumentInitContext ();
48354840 initExpr = param->getTypeCheckedDefaultExpr ();
4841+ enclosingIsolation =
4842+ getActorIsolationOfContext (param->getDeclContext ());
48364843 }
48374844
48384845 if (!dc || !initExpr)
48394846 return ActorIsolation::forUnspecified ();
48404847
4848+ // If the default argument has isolation, it must match the
4849+ // isolation of the decl context.
48414850 ActorIsolationChecker checker (dc);
4842- return checker.computeRequiredIsolation (initExpr);
4851+ auto requiredIsolation = checker.computeRequiredIsolation (initExpr);
4852+ if (requiredIsolation.isActorIsolated ()) {
4853+ if (enclosingIsolation != requiredIsolation) {
4854+ var->diagnose (
4855+ diag::isolated_default_argument_context,
4856+ requiredIsolation, enclosingIsolation);
4857+ return ActorIsolation::forUnspecified ();
4858+ }
4859+ }
4860+
4861+ return requiredIsolation;
48434862}
48444863
48454864void swift::checkOverrideActorIsolation (ValueDecl *value) {
@@ -5955,8 +5974,8 @@ bool swift::isAccessibleAcrossActors(
59555974}
59565975
59575976ActorReferenceResult ActorReferenceResult::forSameConcurrencyDomain (
5958- ActorIsolation isolation) {
5959- return ActorReferenceResult{SameConcurrencyDomain, llvm::None , isolation};
5977+ ActorIsolation isolation, Options options ) {
5978+ return ActorReferenceResult{SameConcurrencyDomain, options , isolation};
59605979}
59615980
59625981ActorReferenceResult ActorReferenceResult::forEntersActor (
@@ -5965,8 +5984,8 @@ ActorReferenceResult ActorReferenceResult::forEntersActor(
59655984}
59665985
59675986ActorReferenceResult ActorReferenceResult::forExitsActorToNonisolated (
5968- ActorIsolation isolation) {
5969- return ActorReferenceResult{ExitsActorToNonisolated, llvm::None , isolation};
5987+ ActorIsolation isolation, Options options ) {
5988+ return ActorReferenceResult{ExitsActorToNonisolated, options , isolation};
59705989}
59715990
59725991// Determine if two actor isolation contexts are considered to be equivalent.
@@ -6002,10 +6021,24 @@ ActorReferenceResult ActorReferenceResult::forReference(
60026021 declIsolation = declIsolation.subst (declRef.getSubstitutions ());
60036022 }
60046023
6024+ // Determine what adjustments we need to perform for cross-actor
6025+ // references.
6026+ Options options = llvm::None;
6027+
6028+ // FIXME: Actor constructors are modeled as isolated to the actor
6029+ // so that Sendable checking is applied to their arguments, but the
6030+ // call itself does not hop to another executor.
6031+ if (auto ctor = dyn_cast<ConstructorDecl>(declRef.getDecl ())) {
6032+ if (auto nominal = ctor->getDeclContext ()->getSelfNominalTypeDecl ()) {
6033+ if (nominal->isAnyActor ())
6034+ options |= Flags::OnlyArgsCrossIsolation;
6035+ }
6036+ }
6037+
60056038 // If the entity we are referencing is not a value, we're in the same
60066039 // concurrency domain.
60076040 if (isNonValueReference (declRef.getDecl ()))
6008- return forSameConcurrencyDomain (declIsolation);
6041+ return forSameConcurrencyDomain (declIsolation, options );
60096042
60106043 // Compute the isolation of the context, if not provided.
60116044 ActorIsolation contextIsolation = ActorIsolation::forUnspecified ();
@@ -6024,11 +6057,11 @@ ActorReferenceResult ActorReferenceResult::forReference(
60246057 if (isAsyncDecl (declRef) && contextIsolation.isActorIsolated () &&
60256058 !declRef.getDecl ()->getAttrs ()
60266059 .hasAttribute <UnsafeInheritExecutorAttr>())
6027- return forExitsActorToNonisolated (contextIsolation);
6060+ return forExitsActorToNonisolated (contextIsolation, options );
60286061
60296062 // Otherwise, we stay in the same concurrency domain, whether on an actor
60306063 // or in a task.
6031- return forSameConcurrencyDomain (declIsolation);
6064+ return forSameConcurrencyDomain (declIsolation, options );
60326065 }
60336066
60346067 // The declaration we are accessing is actor-isolated. First, check whether
@@ -6037,11 +6070,11 @@ ActorReferenceResult ActorReferenceResult::forReference(
60376070 declIsolation.getActorInstanceParameter () == 0 ) {
60386071 // If this instance is isolated, we're in the same concurrency domain.
60396072 if (actorInstance->isIsolated ())
6040- return forSameConcurrencyDomain (declIsolation);
6073+ return forSameConcurrencyDomain (declIsolation, options );
60416074 } else if (equivalentIsolationContexts (declIsolation, contextIsolation)) {
60426075 // The context isolation matches, so we are in the same concurrency
60436076 // domain.
6044- return forSameConcurrencyDomain (declIsolation);
6077+ return forSameConcurrencyDomain (declIsolation, options );
60456078 }
60466079
60476080 // Initializing an actor isolated stored property with a value effectively
@@ -6061,7 +6094,8 @@ ActorReferenceResult ActorReferenceResult::forReference(
60616094 // Treat the decl isolation as 'preconcurrency' to downgrade violations
60626095 // to warnings, because violating Sendable here is accepted by the
60636096 // Swift 5.9 compiler.
6064- return forEntersActor (declIsolation, Flags::Preconcurrency);
6097+ options |= Flags::Preconcurrency;
6098+ return forEntersActor (declIsolation, options);
60656099 }
60666100 }
60676101 }
@@ -6071,7 +6105,7 @@ ActorReferenceResult ActorReferenceResult::forReference(
60716105 if (actorInstance &&
60726106 checkedByFlowIsolation (
60736107 fromDC, *actorInstance, declRef.getDecl (), declRefLoc, useKind))
6074- return forSameConcurrencyDomain (declIsolation);
6108+ return forSameConcurrencyDomain (declIsolation, options );
60756109
60766110 // If we are delegating to another initializer, treat them as being in the
60776111 // same concurrency domain.
@@ -6080,7 +6114,7 @@ ActorReferenceResult ActorReferenceResult::forReference(
60806114 if (actorInstance && actorInstance->isSelf () &&
60816115 isa<ConstructorDecl>(declRef.getDecl ()) &&
60826116 isa<ConstructorDecl>(fromDC))
6083- return forSameConcurrencyDomain (declIsolation);
6117+ return forSameConcurrencyDomain (declIsolation, options );
60846118
60856119 // If there is an instance that corresponds to 'self',
60866120 // we are in a constructor or destructor, and we have a stored property of
@@ -6090,18 +6124,14 @@ ActorReferenceResult ActorReferenceResult::forReference(
60906124 isNonInheritedStorage (declRef.getDecl (), fromDC) &&
60916125 declIsolation.isGlobalActor () &&
60926126 (isa<ConstructorDecl>(fromDC) || isa<DestructorDecl>(fromDC)))
6093- return forSameConcurrencyDomain (declIsolation);
6094-
6095- // Determine what adjustments we need to perform for cross-actor
6096- // references.
6097- Options options = llvm::None;
6127+ return forSameConcurrencyDomain (declIsolation, options);
60986128
60996129 // At this point, we are accessing the target from outside the actor.
61006130 // First, check whether it is something that can be accessed directly,
61016131 // without any kind of promotion.
61026132 if (isAccessibleAcrossActors (
61036133 declRef.getDecl (), declIsolation, fromDC, options, actorInstance))
6104- return forEntersActor (declIsolation, llvm::None );
6134+ return forEntersActor (declIsolation, options );
61056135
61066136 // This is a cross-actor reference.
61076137
0 commit comments