@@ -160,6 +160,227 @@ public struct DiscardingTaskGroup {
160160 let _: Void ? = try await _taskGroupWaitAll ( group: _group, bodyError: nil )
161161 }
162162
163+ // Clone the task-creation routines in Embedded Swift so that we don't
164+ // introduce an implicit use of `any Actor`.
165+ #if !$Embedded
166+
167+ /// Adds a child task to the group.
168+ ///
169+ /// - Parameters:
170+ /// - priority: The priority of the operation task.
171+ /// Omit this parameter or pass `.unspecified`
172+ /// to set the child task's priority to the priority of the group.
173+ /// - operation: The operation to execute as part of the task group.
174+ @_alwaysEmitIntoClient
175+ @_allowFeatureSuppression ( IsolatedAny)
176+ #if SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY
177+ @available ( * , unavailable, message: " Unavailable in task-to-thread concurrency model " , renamed: " addTask(operation:) " )
178+ #endif
179+ public mutating func addTask(
180+ priority: TaskPriority ? = nil ,
181+ operation: __owned @Sendable @escaping @isolated ( any) ( ) async -> Void
182+ ) {
183+ #if SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY
184+ let flags = taskCreateFlags (
185+ priority: priority, isChildTask: true , copyTaskLocals: false ,
186+ inheritContext: false , enqueueJob: false ,
187+ addPendingGroupTaskUnconditionally: true , isDiscardingTask: true
188+ )
189+ #else
190+ let flags = taskCreateFlags (
191+ priority: priority, isChildTask: true , copyTaskLocals: false ,
192+ inheritContext: false , enqueueJob: true ,
193+ addPendingGroupTaskUnconditionally: true , isDiscardingTask: true
194+ )
195+ #endif
196+
197+ // Create the task in this group.
198+ #if $BuiltinCreateTask
199+ let builtinSerialExecutor =
200+ Builtin . extractFunctionIsolation ( operation) ? . unownedExecutor. executor
201+
202+ _ = Builtin . createDiscardingTask ( flags: flags,
203+ initialSerialExecutor: builtinSerialExecutor,
204+ taskGroup: _group,
205+ operation: operation)
206+ #elseif $BuiltinCreateAsyncDiscardingTaskInGroup
207+ _ = Builtin . createAsyncDiscardingTaskInGroup ( flags, _group, operation)
208+ #else
209+ // This builtin happens to work, but the signature of the operation is
210+ // incorrect, as the discarding group uses Void, and therefore has less
211+ // generic parameters than the operation expected to be passed to
212+ // createAsyncTaskInGroup. While this happened to work on some platforms,
213+ // on others this causes issues, e.g. on wasm;
214+ //
215+ // Keep this branch for compatibility with old compilers, but use the
216+ // correct 'createAsyncDiscardingTaskInGroup' when available (and a recent
217+ // enough compiler is used).
218+ _ = Builtin . createAsyncTaskInGroup ( flags, _group, operation)
219+ #endif
220+ }
221+
222+ /// Adds a child task to the group, unless the group has been canceled.
223+ ///
224+ /// - Parameters:
225+ /// - priority: The priority of the operation task.
226+ /// Omit this parameter or pass `.unspecified`
227+ /// to set the child task's priority to the priority of the group.
228+ /// - operation: The operation to execute as part of the task group.
229+ /// - Returns: `true` if the child task was added to the group;
230+ /// otherwise `false`.
231+ @_alwaysEmitIntoClient
232+ @_allowFeatureSuppression ( IsolatedAny)
233+ #if SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY
234+ @available ( * , unavailable, message: " Unavailable in task-to-thread concurrency model " , renamed: " addTask(operation:) " )
235+ #endif
236+ public mutating func addTaskUnlessCancelled(
237+ priority: TaskPriority ? = nil ,
238+ operation: __owned @Sendable @escaping @isolated ( any) ( ) async -> Void
239+ ) -> Bool {
240+ let canAdd = _taskGroupAddPendingTask ( group: _group, unconditionally: false )
241+
242+ guard canAdd else {
243+ // the group is cancelled and is not accepting any new work
244+ return false
245+ }
246+ #if SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY
247+ let flags = taskCreateFlags (
248+ priority: priority, isChildTask: true , copyTaskLocals: false ,
249+ inheritContext: false , enqueueJob: false ,
250+ addPendingGroupTaskUnconditionally: false , isDiscardingTask: true
251+ )
252+ #else
253+ let flags = taskCreateFlags (
254+ priority: priority, isChildTask: true , copyTaskLocals: false ,
255+ inheritContext: false , enqueueJob: true ,
256+ addPendingGroupTaskUnconditionally: false , isDiscardingTask: true
257+ )
258+ #endif
259+
260+ // Create the task in this group.
261+ #if $BuiltinCreateTask
262+ let builtinSerialExecutor =
263+ Builtin . extractFunctionIsolation ( operation) ? . unownedExecutor. executor
264+
265+ _ = Builtin . createDiscardingTask ( flags: flags,
266+ initialSerialExecutor: builtinSerialExecutor,
267+ taskGroup: _group,
268+ operation: operation)
269+ #elseif $BuiltinCreateAsyncDiscardingTaskInGroup
270+ _ = Builtin . createAsyncDiscardingTaskInGroup ( flags, _group, operation)
271+ #else
272+ // This builtin happens to work, but the signature of the operation is
273+ // incorrect, as the discarding group uses Void, and therefore has less
274+ // generic parameters than the operation expected to be passed to
275+ // createAsyncTaskInGroup. While this happened to work on some platforms,
276+ // on others this causes issues, e.g. on wasm;
277+ //
278+ // Keep this branch for compatibility with old compilers, but use the
279+ // correct 'createAsyncDiscardingTaskInGroup' when available (and a recent
280+ // enough compiler is used).
281+ _ = Builtin . createAsyncTaskInGroup ( flags, _group, operation)
282+ #endif
283+
284+ return true
285+ }
286+
287+ @_alwaysEmitIntoClient
288+ @_allowFeatureSuppression ( IsolatedAny)
289+ public mutating func addTask(
290+ operation: __owned @Sendable @escaping @isolated ( any) ( ) async -> Void
291+ ) {
292+ let flags = taskCreateFlags (
293+ priority: nil , isChildTask: true , copyTaskLocals: false ,
294+ inheritContext: false , enqueueJob: true ,
295+ addPendingGroupTaskUnconditionally: true , isDiscardingTask: true
296+ )
297+
298+ // Create the task in this group.
299+ #if $BuiltinCreateTask
300+ let builtinSerialExecutor =
301+ Builtin . extractFunctionIsolation ( operation) ? . unownedExecutor. executor
302+
303+ _ = Builtin . createDiscardingTask ( flags: flags,
304+ initialSerialExecutor: builtinSerialExecutor,
305+ taskGroup: _group,
306+ operation: operation)
307+ #elseif $BuiltinCreateAsyncDiscardingTaskInGroup
308+ _ = Builtin . createAsyncDiscardingTaskInGroup ( flags, _group, operation)
309+ #else
310+ // This builtin happens to work, but the signature of the operation is
311+ // incorrect, as the discarding group uses Void, and therefore has less
312+ // generic parameters than the operation expected to be passed to
313+ // createAsyncTaskInGroup. While this happened to work on some platforms,
314+ // on others this causes issues, e.g. on wasm;
315+ //
316+ // Keep this branch for compatibility with old compilers, but use the
317+ // correct 'createAsyncDiscardingTaskInGroup' when available (and a recent
318+ // enough compiler is used).
319+ _ = Builtin . createAsyncTaskInGroup ( flags, _group, operation)
320+ #endif
321+ }
322+
323+ /// Adds a child task to the group, unless the group has been canceled.
324+ ///
325+ /// - Parameters:
326+ /// - operation: The operation to execute as part of the task group.
327+ /// - Returns: `true` if the child task was added to the group;
328+ /// otherwise `false`.
329+ #if SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY
330+ @available ( * , unavailable, message: " Unavailable in task-to-thread concurrency model " , renamed: " addTaskUnlessCancelled(operation:) " )
331+ #endif
332+ @_allowFeatureSuppression ( IsolatedAny)
333+ @_alwaysEmitIntoClient
334+ public mutating func addTaskUnlessCancelled(
335+ operation: __owned @Sendable @escaping @isolated ( any) ( ) async -> Void
336+ ) -> Bool {
337+ #if compiler(>=5.5) && $BuiltinCreateAsyncTaskInGroup
338+ let canAdd = _taskGroupAddPendingTask ( group: _group, unconditionally: false )
339+
340+ guard canAdd else {
341+ // the group is cancelled and is not accepting any new work
342+ return false
343+ }
344+
345+ let flags = taskCreateFlags (
346+ priority: nil , isChildTask: true , copyTaskLocals: false ,
347+ inheritContext: false , enqueueJob: true ,
348+ addPendingGroupTaskUnconditionally: false , isDiscardingTask: true
349+ )
350+
351+ // Create the task in this group.
352+ #if $BuiltinCreateTask
353+ let builtinSerialExecutor =
354+ Builtin . extractFunctionIsolation ( operation) ? . unownedExecutor. executor
355+
356+ _ = Builtin . createDiscardingTask ( flags: flags,
357+ initialSerialExecutor: builtinSerialExecutor,
358+ taskGroup: _group,
359+ operation: operation)
360+ #elseif $BuiltinCreateAsyncDiscardingTaskInGroup
361+ _ = Builtin . createAsyncDiscardingTaskInGroup ( flags, _group, operation)
362+ #else
363+ // This builtin happens to work, but the signature of the operation is
364+ // incorrect, as the discarding group uses Void, and therefore has less
365+ // generic parameters than the operation expected to be passed to
366+ // createAsyncTaskInGroup. While this happened to work on some platforms,
367+ // on others this causes issues, e.g. on wasm;
368+ //
369+ // Keep this branch for compatibility with old compilers, but use the
370+ // correct 'createAsyncDiscardingTaskInGroup' when available (and a recent
371+ // enough compiler is used).
372+ _ = Builtin . createAsyncTaskInGroup ( flags, _group, operation)
373+ #endif
374+
375+ return true
376+ #else
377+ fatalError ( " Unsupported Swift compiler " )
378+ #endif
379+ }
380+
381+ // The Embedded clones of the task-creation routines.
382+ #else
383+
163384 /// Adds a child task to the group.
164385 ///
165386 /// - Parameters:
@@ -338,6 +559,8 @@ public struct DiscardingTaskGroup {
338559#endif
339560 }
340561
562+ #endif // $Embedded
563+
341564 /// A Boolean value that indicates whether the group has any remaining tasks.
342565 ///
343566 /// At the start of the body of a `withDiscardingTaskGroup(of:returning:body:)` call,
@@ -604,9 +827,10 @@ public struct ThrowingDiscardingTaskGroup<Failure: Error> {
604827 @available ( * , unavailable, message: " Unavailable in task-to-thread concurrency model " , renamed: " addTask(operation:) " )
605828#endif
606829 @_alwaysEmitIntoClient
830+ @_allowFeatureSuppression ( IsolatedAny)
607831 public mutating func addTask(
608832 priority: TaskPriority ? = nil ,
609- operation: __owned @Sendable @escaping ( ) async throws -> Void
833+ operation: __owned @Sendable @escaping @ isolated ( any ) ( ) async throws -> Void
610834 ) {
611835#if compiler(>=5.5) && $BuiltinCreateAsyncTaskInGroup
612836 let flags = taskCreateFlags (
@@ -616,7 +840,15 @@ public struct ThrowingDiscardingTaskGroup<Failure: Error> {
616840 )
617841
618842 // Create the task in this group.
619- #if $BuiltinCreateAsyncDiscardingTaskInGroup
843+ #if $BuiltinCreateTask
844+ let builtinSerialExecutor =
845+ Builtin . extractFunctionIsolation ( operation) ? . unownedExecutor. executor
846+
847+ _ = Builtin . createDiscardingTask ( flags: flags,
848+ initialSerialExecutor: builtinSerialExecutor,
849+ taskGroup: _group,
850+ operation: operation)
851+ #elseif $BuiltinCreateAsyncDiscardingTaskInGroup
620852 _ = Builtin . createAsyncDiscardingTaskInGroup ( flags, _group, operation)
621853 #else
622854 // This builtin happens to work, but the signature of the operation is
@@ -639,9 +871,10 @@ public struct ThrowingDiscardingTaskGroup<Failure: Error> {
639871 @available ( * , unavailable, message: " Unavailable in task-to-thread concurrency model " , renamed: " addTask(operation:) " )
640872#endif
641873 @_alwaysEmitIntoClient
874+ @_allowFeatureSuppression ( IsolatedAny)
642875 public mutating func addTaskUnlessCancelled(
643876 priority: TaskPriority ? = nil ,
644- operation: __owned @Sendable @escaping ( ) async throws -> Void
877+ operation: __owned @Sendable @escaping @ isolated ( any ) ( ) async throws -> Void
645878 ) -> Bool {
646879#if compiler(>=5.5) && $BuiltinCreateAsyncTaskInGroup
647880 let canAdd = _taskGroupAddPendingTask ( group: _group, unconditionally: false )
@@ -658,7 +891,15 @@ public struct ThrowingDiscardingTaskGroup<Failure: Error> {
658891 )
659892
660893 // Create the task in this group.
661- #if $BuiltinCreateAsyncDiscardingTaskInGroup
894+ #if $BuiltinCreateTask
895+ let builtinSerialExecutor =
896+ Builtin . extractFunctionIsolation ( operation) ? . unownedExecutor. executor
897+
898+ _ = Builtin . createDiscardingTask ( flags: flags,
899+ initialSerialExecutor: builtinSerialExecutor,
900+ taskGroup: _group,
901+ operation: operation)
902+ #elseif $BuiltinCreateAsyncDiscardingTaskInGroup
662903 _ = Builtin . createAsyncDiscardingTaskInGroup ( flags, _group, operation)
663904 #else
664905 // This builtin happens to work, but the signature of the operation is
0 commit comments