@@ -3143,7 +3143,10 @@ namespace {
31433143 if (!unsatisfiedIsolation)
31443144 return false ;
31453145
3146- if (refineRequiredIsolation (*unsatisfiedIsolation))
3146+ bool onlyArgsCrossIsolation = callOptions.contains (
3147+ ActorReferenceResult::Flags::OnlyArgsCrossIsolation);
3148+ if (!onlyArgsCrossIsolation &&
3149+ refineRequiredIsolation (*unsatisfiedIsolation))
31473150 return false ;
31483151
31493152 // At this point, we know a jump is made to the callee that yields
@@ -4757,14 +4760,19 @@ DefaultInitializerIsolation::evaluate(Evaluator &evaluator,
47574760
47584761 Initializer *dc = nullptr ;
47594762 Expr *initExpr = nullptr ;
4763+ ActorIsolation enclosingIsolation;
47604764
47614765 if (auto *pbd = var->getParentPatternBinding ()) {
47624766 if (!var->isParentInitialized ())
47634767 return ActorIsolation::forUnspecified ();
47644768
47654769 auto i = pbd->getPatternEntryIndexForVarDecl (var);
4770+ if (!pbd->isInitializerChecked (i))
4771+ TypeChecker::typeCheckPatternBinding (pbd, i);
4772+
47664773 dc = cast<Initializer>(pbd->getInitContext (i));
4767- initExpr = var->getParentInitializer ();
4774+ initExpr = pbd->getInit (i);
4775+ enclosingIsolation = getActorIsolation (var);
47684776 } else if (auto *param = dyn_cast<ParamDecl>(var)) {
47694777 // If this parameter corresponds to a stored property for a
47704778 // memberwise initializer, the default argument is the default
@@ -4782,13 +4790,27 @@ DefaultInitializerIsolation::evaluate(Evaluator &evaluator,
47824790
47834791 dc = param->getDefaultArgumentInitContext ();
47844792 initExpr = param->getTypeCheckedDefaultExpr ();
4793+ enclosingIsolation =
4794+ getActorIsolationOfContext (param->getDeclContext ());
47854795 }
47864796
47874797 if (!dc || !initExpr)
47884798 return ActorIsolation::forUnspecified ();
47894799
4800+ // If the default argument has isolation, it must match the
4801+ // isolation of the decl context.
47904802 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;
47924814}
47934815
47944816void swift::checkOverrideActorIsolation (ValueDecl *value) {
@@ -5859,8 +5881,8 @@ bool swift::isAccessibleAcrossActors(
58595881}
58605882
58615883ActorReferenceResult ActorReferenceResult::forSameConcurrencyDomain (
5862- ActorIsolation isolation) {
5863- return ActorReferenceResult{SameConcurrencyDomain, llvm::None , isolation};
5884+ ActorIsolation isolation, Options options ) {
5885+ return ActorReferenceResult{SameConcurrencyDomain, options , isolation};
58645886}
58655887
58665888ActorReferenceResult ActorReferenceResult::forEntersActor (
@@ -5869,8 +5891,8 @@ ActorReferenceResult ActorReferenceResult::forEntersActor(
58695891}
58705892
58715893ActorReferenceResult ActorReferenceResult::forExitsActorToNonisolated (
5872- ActorIsolation isolation) {
5873- return ActorReferenceResult{ExitsActorToNonisolated, llvm::None , isolation};
5894+ ActorIsolation isolation, Options options ) {
5895+ return ActorReferenceResult{ExitsActorToNonisolated, options , isolation};
58745896}
58755897
58765898// Determine if two actor isolation contexts are considered to be equivalent.
@@ -5906,10 +5928,24 @@ ActorReferenceResult ActorReferenceResult::forReference(
59065928 declIsolation = declIsolation.subst (declRef.getSubstitutions ());
59075929 }
59085930
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+
59095945 // If the entity we are referencing is not a value, we're in the same
59105946 // concurrency domain.
59115947 if (isNonValueReference (declRef.getDecl ()))
5912- return forSameConcurrencyDomain (declIsolation);
5948+ return forSameConcurrencyDomain (declIsolation, options );
59135949
59145950 // Compute the isolation of the context, if not provided.
59155951 ActorIsolation contextIsolation = ActorIsolation::forUnspecified ();
@@ -5928,11 +5964,11 @@ ActorReferenceResult ActorReferenceResult::forReference(
59285964 if (isAsyncDecl (declRef) && contextIsolation.isActorIsolated () &&
59295965 !declRef.getDecl ()->getAttrs ()
59305966 .hasAttribute <UnsafeInheritExecutorAttr>())
5931- return forExitsActorToNonisolated (contextIsolation);
5967+ return forExitsActorToNonisolated (contextIsolation, options );
59325968
59335969 // Otherwise, we stay in the same concurrency domain, whether on an actor
59345970 // or in a task.
5935- return forSameConcurrencyDomain (declIsolation);
5971+ return forSameConcurrencyDomain (declIsolation, options );
59365972 }
59375973
59385974 // The declaration we are accessing is actor-isolated. First, check whether
@@ -5941,11 +5977,11 @@ ActorReferenceResult ActorReferenceResult::forReference(
59415977 declIsolation.getActorInstanceParameter () == 0 ) {
59425978 // If this instance is isolated, we're in the same concurrency domain.
59435979 if (actorInstance->isIsolated ())
5944- return forSameConcurrencyDomain (declIsolation);
5980+ return forSameConcurrencyDomain (declIsolation, options );
59455981 } else if (equivalentIsolationContexts (declIsolation, contextIsolation)) {
59465982 // The context isolation matches, so we are in the same concurrency
59475983 // domain.
5948- return forSameConcurrencyDomain (declIsolation);
5984+ return forSameConcurrencyDomain (declIsolation, options );
59495985 }
59505986
59515987 // Initializing an actor isolated stored property with a value effectively
@@ -5965,7 +6001,8 @@ ActorReferenceResult ActorReferenceResult::forReference(
59656001 // Treat the decl isolation as 'preconcurrency' to downgrade violations
59666002 // to warnings, because violating Sendable here is accepted by the
59676003 // Swift 5.9 compiler.
5968- return forEntersActor (declIsolation, Flags::Preconcurrency);
6004+ options |= Flags::Preconcurrency;
6005+ return forEntersActor (declIsolation, options);
59696006 }
59706007 }
59716008 }
@@ -5975,7 +6012,7 @@ ActorReferenceResult ActorReferenceResult::forReference(
59756012 if (actorInstance &&
59766013 checkedByFlowIsolation (
59776014 fromDC, *actorInstance, declRef.getDecl (), declRefLoc, useKind))
5978- return forSameConcurrencyDomain (declIsolation);
6015+ return forSameConcurrencyDomain (declIsolation, options );
59796016
59806017 // If we are delegating to another initializer, treat them as being in the
59816018 // same concurrency domain.
@@ -5984,7 +6021,7 @@ ActorReferenceResult ActorReferenceResult::forReference(
59846021 if (actorInstance && actorInstance->isSelf () &&
59856022 isa<ConstructorDecl>(declRef.getDecl ()) &&
59866023 isa<ConstructorDecl>(fromDC))
5987- return forSameConcurrencyDomain (declIsolation);
6024+ return forSameConcurrencyDomain (declIsolation, options );
59886025
59896026 // If there is an instance that corresponds to 'self',
59906027 // we are in a constructor or destructor, and we have a stored property of
@@ -5994,18 +6031,14 @@ ActorReferenceResult ActorReferenceResult::forReference(
59946031 isNonInheritedStorage (declRef.getDecl (), fromDC) &&
59956032 declIsolation.isGlobalActor () &&
59966033 (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);
60026035
60036036 // At this point, we are accessing the target from outside the actor.
60046037 // First, check whether it is something that can be accessed directly,
60056038 // without any kind of promotion.
60066039 if (isAccessibleAcrossActors (
60076040 declRef.getDecl (), declIsolation, fromDC, options, actorInstance))
6008- return forEntersActor (declIsolation, llvm::None );
6041+ return forEntersActor (declIsolation, options );
60096042
60106043 // This is a cross-actor reference.
60116044
0 commit comments