@@ -1939,6 +1939,12 @@ namespace {
19391939 llvm::function_ref<ActorIsolation(AbstractClosureExpr *)>
19401940 getClosureActorIsolation;
19411941
1942+ bool shouldRefineIsolation = false ;
1943+
1944+ // / Used under the mode to compute required actor isolation for
1945+ // / an expression or function.
1946+ ActorIsolation requiredIsolation = ActorIsolation::forNonisolated();
1947+
19421948 // / Keeps track of the capture context of variables that have been
19431949 // / explicitly captured in closures.
19441950 llvm::SmallDenseMap<VarDecl *, TinyPtrVector<const DeclContext *>>
@@ -2123,6 +2129,65 @@ namespace {
21232129 }
21242130 }
21252131
2132+ bool refineRequiredIsolation (ActorIsolation refinedIsolation) {
2133+ if (!shouldRefineIsolation)
2134+ return false ;
2135+
2136+ if (auto *closure = dyn_cast<AbstractClosureExpr>(getDeclContext ())) {
2137+ // We cannot infer a more specific actor isolation for a @Sendable
2138+ // closure. It is an error to cast away actor isolation from a function
2139+ // type, but this is okay for non-Sendable closures because they cannot
2140+ // leave the isolation domain they're created in anyway.
2141+ if (closure->isSendable ())
2142+ return false ;
2143+
2144+ if (closure->getActorIsolation ().isActorIsolated ())
2145+ return false ;
2146+ }
2147+
2148+ // To refine the required isolation, the existing requirement
2149+ // must either be 'nonisolated' or exactly the same as the
2150+ // new refinement.
2151+ if (requiredIsolation == ActorIsolation::Nonisolated ||
2152+ requiredIsolation == refinedIsolation) {
2153+ requiredIsolation = refinedIsolation;
2154+ return true ;
2155+ }
2156+
2157+ return false ;
2158+ }
2159+
2160+ void checkDefaultArgument (DefaultArgumentExpr *expr) {
2161+ // Check the context isolation against the required isolation for
2162+ // evaluating the default argument synchronously. If the default
2163+ // argument must be evaluated asynchronously, it must be written
2164+ // explicitly in the argument list with 'await'.
2165+ auto requiredIsolation = expr->getRequiredIsolation ();
2166+ auto contextIsolation = getInnermostIsolatedContext (
2167+ getDeclContext (), getClosureActorIsolation);
2168+
2169+ if (requiredIsolation == contextIsolation)
2170+ return ;
2171+
2172+ switch (requiredIsolation) {
2173+ // Nonisolated is okay from any caller isolation because
2174+ // default arguments cannot have any async calls.
2175+ case ActorIsolation::Unspecified:
2176+ case ActorIsolation::Nonisolated:
2177+ return ;
2178+
2179+ case ActorIsolation::GlobalActor:
2180+ case ActorIsolation::GlobalActorUnsafe:
2181+ case ActorIsolation::ActorInstance:
2182+ break ;
2183+ }
2184+
2185+ auto &ctx = getDeclContext ()->getASTContext ();
2186+ ctx.Diags .diagnose (
2187+ expr->getLoc (), diag::isolated_default_argument,
2188+ requiredIsolation, contextIsolation);
2189+ }
2190+
21262191 // / Check closure captures for Sendable violations.
21272192 void checkLocalCaptures (AnyFunctionRef localFunc) {
21282193 SmallVector<CapturedValue, 2 > captures;
@@ -2180,6 +2245,16 @@ namespace {
21802245 contextStack.push_back (dc);
21812246 }
21822247
2248+ ActorIsolation computeRequiredIsolation (Expr *expr) {
2249+ auto &ctx = getDeclContext ()->getASTContext ();
2250+
2251+ shouldRefineIsolation =
2252+ ctx.LangOpts .hasFeature (Feature::IsolatedDefaultArguments);
2253+ expr->walk (*this );
2254+ shouldRefineIsolation = false ;
2255+ return requiredIsolation;
2256+ }
2257+
21832258 // / Searches the applyStack from back to front for the inner-most CallExpr
21842259 // / and marks that CallExpr as implicitly async.
21852260 // /
@@ -2375,6 +2450,10 @@ namespace {
23752450 checkFunctionConversion (funcConv);
23762451 }
23772452
2453+ if (auto *defaultArg = dyn_cast<DefaultArgumentExpr>(expr)) {
2454+ checkDefaultArgument (defaultArg);
2455+ }
2456+
23782457 return Action::Continue (expr);
23792458 }
23802459
@@ -2920,6 +2999,9 @@ namespace {
29202999 if (!unsatisfiedIsolation)
29213000 return false ;
29223001
3002+ if (refineRequiredIsolation (*unsatisfiedIsolation))
3003+ return false ;
3004+
29233005 // At this point, we know a jump is made to the callee that yields
29243006 // an isolation requirement unsatisfied by the calling context, so
29253007 // set the unsatisfiedIsolationJump fields of the ApplyExpr appropriately
@@ -3255,6 +3337,14 @@ namespace {
32553337
32563338 case AsyncMarkingResult::SyncContext:
32573339 case AsyncMarkingResult::NotFound:
3340+ // If we found an implicitly async reference in a sync
3341+ // context and we're computing the required isolation for
3342+ // an expression, the calling context requires the isolation
3343+ // of the reference.
3344+ if (refineRequiredIsolation (result.isolation )) {
3345+ return false ;
3346+ }
3347+
32583348 // Complain about access outside of the isolation domain.
32593349 auto useKind = static_cast <unsigned >(
32603350 kindOfUsage (decl, context).value_or (VarRefUseEnv::Read));
@@ -3467,6 +3557,12 @@ void swift::checkInitializerActorIsolation(Initializer *init, Expr *expr) {
34673557 expr->walk (checker);
34683558}
34693559
3560+ ActorIsolation
3561+ swift::computeRequiredIsolation (Initializer *init, Expr *expr) {
3562+ ActorIsolationChecker checker (init);
3563+ return checker.computeRequiredIsolation (expr);
3564+ }
3565+
34703566void swift::checkEnumElementActorIsolation (
34713567 EnumElementDecl *element, Expr *expr) {
34723568 ActorIsolationChecker checker (element);
0 commit comments