@@ -990,6 +990,21 @@ SILIsolationInfo SILIsolationInfo::get(SILArgument *arg) {
990990 if (fArg ->isSending ())
991991 return SILIsolationInfo::getDisconnected (false /* nonisolated(unsafe)*/ );
992992
993+ // Check if we have a closure captured parameter that is nonisolated(unsafe)
994+ // at its original declaration sign. In such a case, we want to propagate that
995+ // bit.
996+ bool isClosureCapturedNonisolatedUnsafe = [&]() -> bool {
997+ if (!fArg ->isClosureCapture ())
998+ return false ;
999+ auto *decl = fArg ->getDecl ();
1000+ if (!decl)
1001+ return false ;
1002+ auto *attr = decl->getAttrs ().getAttribute <NonisolatedAttr>();
1003+ if (!attr)
1004+ return false ;
1005+ return attr->isUnsafe ();
1006+ }();
1007+
9931008 // If we have a closure capture that is not an indirect result or indirect
9941009 // result error, we want to treat it as sending so that we properly handle
9951010 // async lets.
@@ -1001,7 +1016,8 @@ SILIsolationInfo SILIsolationInfo::get(SILArgument *arg) {
10011016 fArg ->isClosureCapture ()) {
10021017 if (auto declRef = arg->getFunction ()->getDeclRef ();
10031018 declRef && declRef.isAsyncLetClosure ) {
1004- return SILIsolationInfo::getDisconnected (false /* nonisolated(unsafe)*/ );
1019+ return SILIsolationInfo::getDisconnected (
1020+ isClosureCapturedNonisolatedUnsafe);
10051021 }
10061022 }
10071023
@@ -1014,12 +1030,20 @@ SILIsolationInfo SILIsolationInfo::get(SILArgument *arg) {
10141030 if (auto funcIsolation = fArg ->getFunction ()->getActorIsolation ();
10151031 funcIsolation && funcIsolation->isCallerIsolationInheriting ()) {
10161032 return SILIsolationInfo::getTaskIsolated (fArg )
1017- .withNonisolatedNonsendingTaskIsolated (true );
1033+ .withNonisolatedNonsendingTaskIsolated (true )
1034+ .withUnsafeNonIsolated (isClosureCapturedNonisolatedUnsafe);
10181035 }
10191036
10201037 auto astType = isolatedArg->getType ().getASTType ();
10211038 if (astType->lookThroughAllOptionalTypes ()->getAnyActor ()) {
1022- return SILIsolationInfo::getActorInstanceIsolated (fArg , isolatedArg);
1039+ if (auto isolation =
1040+ SILIsolationInfo::getActorInstanceIsolated (fArg , isolatedArg)) {
1041+ return isolation.withUnsafeNonIsolated (
1042+ isClosureCapturedNonisolatedUnsafe);
1043+ }
1044+ // If we had an isolated parameter that was an actor type, but we did not
1045+ // find any isolation for the actor instance... return {}.
1046+ return {};
10231047 }
10241048 }
10251049
@@ -1061,12 +1085,14 @@ SILIsolationInfo SILIsolationInfo::get(SILArgument *arg) {
10611085 }
10621086
10631087 // Otherwise, if we do not have an isolated argument and are not in an
1064- // allocator, then we might be isolated via global isolation.
1088+ // allocator, then we might be isolated via global isolation or in a global
1089+ // actor isolated initializer.
10651090 if (auto functionIsolation = fArg ->getFunction ()->getActorIsolation ()) {
10661091 if (functionIsolation->isActorIsolated ()) {
10671092 if (functionIsolation->isGlobalActor ()) {
10681093 return SILIsolationInfo::getGlobalActorIsolated (
1069- fArg , functionIsolation->getGlobalActor ());
1094+ fArg , functionIsolation->getGlobalActor ())
1095+ .withUnsafeNonIsolated (isClosureCapturedNonisolatedUnsafe);
10701096 }
10711097
10721098 return SILIsolationInfo::getActorInstanceIsolated (
@@ -1075,7 +1101,8 @@ SILIsolationInfo SILIsolationInfo::get(SILArgument *arg) {
10751101 }
10761102 }
10771103
1078- return SILIsolationInfo::getTaskIsolated (fArg );
1104+ return SILIsolationInfo::getTaskIsolated (fArg ).withUnsafeNonIsolated (
1105+ isClosureCapturedNonisolatedUnsafe);
10791106}
10801107
10811108// / Infer isolation region from the set of protocol conformances.
0 commit comments