@@ -3045,35 +3045,47 @@ static void emitDelayedArguments(SILGenFunction &SGF,
3045
3045
done:
3046
3046
3047
3047
if (defaultArgIsolation) {
3048
- assert (SGF.F .isAsync ());
3049
3048
assert (!isolatedArgs.empty ());
3050
3049
3051
- auto &firstArg = *std::get<0 >(isolatedArgs[0 ]);
3052
- auto loc = firstArg.getDefaultArgLoc ();
3050
+ // Only hop to the default arg isolation if the callee is async.
3051
+ // If we're in a synchronous function, the isolation has to match,
3052
+ // so no hop is required. This is enforced by the actor isolation
3053
+ // checker.
3054
+ //
3055
+ // FIXME: Note that we don't end up in this situation for user-written
3056
+ // synchronous functions, because the default argument is only considered
3057
+ // isolated to the callee if the call crosses an isolation boundary. We
3058
+ // do end up here for default argument generators and stored property
3059
+ // initializers. An alternative (and better) approach is to formally model
3060
+ // those generator functions as isolated.
3061
+ if (SGF.F .isAsync ()) {
3062
+ auto &firstArg = *std::get<0 >(isolatedArgs[0 ]);
3063
+ auto loc = firstArg.getDefaultArgLoc ();
3064
+
3065
+ SILValue executor;
3066
+ switch (*defaultArgIsolation) {
3067
+ case ActorIsolation::GlobalActor:
3068
+ executor = SGF.emitLoadGlobalActorExecutor (
3069
+ defaultArgIsolation->getGlobalActor ());
3070
+ break ;
3053
3071
3054
- SILValue executor;
3055
- switch (*defaultArgIsolation) {
3056
- case ActorIsolation::GlobalActor:
3057
- executor = SGF.emitLoadGlobalActorExecutor (
3058
- defaultArgIsolation->getGlobalActor ());
3059
- break ;
3072
+ case ActorIsolation::ActorInstance:
3073
+ llvm_unreachable (" default arg cannot be actor instance isolated" );
3060
3074
3061
- case ActorIsolation::ActorInstance :
3062
- llvm_unreachable (" default arg cannot be actor instance isolated " );
3075
+ case ActorIsolation::Erased :
3076
+ llvm_unreachable (" default arg cannot have erased isolation " );
3063
3077
3064
- case ActorIsolation::Erased:
3065
- llvm_unreachable (" default arg cannot have erased isolation" );
3078
+ case ActorIsolation::Unspecified:
3079
+ case ActorIsolation::Nonisolated:
3080
+ case ActorIsolation::NonisolatedUnsafe:
3081
+ llvm_unreachable (" Not isolated" );
3082
+ }
3066
3083
3067
- case ActorIsolation::Unspecified:
3068
- case ActorIsolation::Nonisolated:
3069
- case ActorIsolation::NonisolatedUnsafe:
3070
- llvm_unreachable (" Not isolated" );
3084
+ // Hop to the target isolation domain once to evaluate all
3085
+ // default arguments.
3086
+ SGF.emitHopToTargetExecutor (loc, executor);
3071
3087
}
3072
3088
3073
- // Hop to the target isolation domain once to evaluate all
3074
- // default arguments.
3075
- SGF.emitHopToTargetExecutor (loc, executor);
3076
-
3077
3089
size_t argsEmitted = 0 ;
3078
3090
for (auto &isolatedArg : isolatedArgs) {
3079
3091
auto &delayedArg = *std::get<0 >(isolatedArg);
0 commit comments