@@ -4056,6 +4056,39 @@ static Type applyUnsafeConcurrencyToParameterType(
40564056 .withGlobalActor (globalActor));
40574057}
40584058
4059+ // / Determine whether the given name is that of a DispatchQueue operation that
4060+ // / takes a closure to be executed on the queue.
4061+ bool swift::isDispatchQueueOperationName (StringRef name) {
4062+ return llvm::StringSwitch<bool >(name)
4063+ .Case (" sync" , true )
4064+ .Case (" async" , true )
4065+ .Case (" asyncAndWait" , true )
4066+ .Case (" asyncAfter" , true )
4067+ .Case (" concurrentPerform" , true )
4068+ .Default (false );
4069+ }
4070+
4071+ // / Determine whether this function is implicitly known to have its
4072+ // / parameters of function type be @_unsafeSendable.
4073+ // /
4074+ // / This hard-codes knowledge of a number of functions that will
4075+ // / eventually have @_unsafeSendable and, eventually, @Sendable,
4076+ // / on their parameters of function type.
4077+ static bool hasKnownUnsafeSendableFunctionParams (AbstractFunctionDecl *func) {
4078+ auto nominal = func->getDeclContext ()->getSelfNominalTypeDecl ();
4079+ if (!nominal)
4080+ return false ;
4081+
4082+ // DispatchQueue operations.
4083+ auto nominalName = nominal->getName ().str ();
4084+ if (nominalName == " DispatchQueue" ) {
4085+ auto name = func->getBaseName ().userFacingName ();
4086+ return isDispatchQueueOperationName (name);
4087+ }
4088+
4089+ return false ;
4090+ }
4091+
40594092// / Apply @_unsafeSendable and @_unsafeMainActor to the parameters of the
40604093// / given function.
40614094static AnyFunctionType *applyUnsafeConcurrencyToFunctionType (
@@ -4079,6 +4112,7 @@ static AnyFunctionType *applyUnsafeConcurrencyToFunctionType(
40794112 auto typeParams = fnType->getParams ();
40804113 auto paramDecls = func->getParameters ();
40814114 assert (typeParams.size () == paramDecls->size ());
4115+ bool knownUnsafeParams = hasKnownUnsafeSendableFunctionParams (func);
40824116 for (unsigned index : indices (typeParams)) {
40834117 auto param = typeParams[index];
40844118 auto paramDecl = (*paramDecls)[index];
@@ -4089,12 +4123,11 @@ static AnyFunctionType *applyUnsafeConcurrencyToFunctionType(
40894123 // application.
40904124 bool isSendable =
40914125 (paramDecl->getAttrs ().hasAttribute <UnsafeSendableAttr>() ||
4092- func-> hasKnownUnsafeSendableFunctionParams () ) &&
4126+ knownUnsafeParams ) &&
40934127 inConcurrencyContext;
40944128 bool isMainActor =
40954129 (paramDecl->getAttrs ().hasAttribute <UnsafeMainActorAttr>() ||
4096- (isMainDispatchQueue &&
4097- func->hasKnownUnsafeSendableFunctionParams ())) &&
4130+ (isMainDispatchQueue && knownUnsafeParams)) &&
40984131 (inConcurrencyContext || numApplies >= 1 );
40994132
41004133 if (!isSendable && !isMainActor) {
@@ -4110,7 +4143,6 @@ static AnyFunctionType *applyUnsafeConcurrencyToFunctionType(
41104143 newTypeParams.append (typeParams.begin (), typeParams.begin () + index);
41114144 }
41124145
4113-
41144146 // Transform the parameter type.
41154147 Type newParamType = applyUnsafeConcurrencyToParameterType (
41164148 param.getPlainType (), isSendable, isMainActor);
@@ -4140,7 +4172,7 @@ static AnyFunctionType *applyUnsafeConcurrencyToFunctionType(
41404172 outerFnType->getParams (), Type (fnType), outerFnType->getExtInfo ());
41414173}
41424174
4143- AnyFunctionType *swift::applyGlobalActorType (
4175+ AnyFunctionType *swift::adjustFunctionTypeForConcurrency (
41444176 AnyFunctionType *fnType, ValueDecl *funcOrEnum, DeclContext *dc,
41454177 unsigned numApplies, bool isMainDispatchQueue) {
41464178 // Apply unsafe concurrency features to the given function type.
0 commit comments