@@ -26,7 +26,7 @@ import Swift
2626% [ # PARAMS
2727% 'name: String? = nil',
2828% 'priority: TaskPriority? = nil',
29- % '@_inheritActorContext @_implicitSelfCapture operation: sending @escaping @isolated(any) () async throws -> Success',
29+ % '@_inheritActorContext @_implicitSelfCapture operation: sending @escaping @isolated(any) () async throws(Failure) -> Success',
3030% ]),
3131% # ==== --------------------------------------------------------------------
3232% ([ # METHOD_VARIANT
@@ -40,7 +40,7 @@ import Swift
4040% [ # PARAMS
4141% 'name: String? = nil',
4242% 'priority: TaskPriority? = nil',
43- % 'operation: sending @escaping @isolated(any) () async throws -> Success',
43+ % 'operation: sending @escaping @isolated(any) () async throws(Failure) -> Success',
4444% ]),
4545% # ==== -------------------------------------------------------------------------------------------------------------
4646% # ==== With task executor, but available only since 6.0
@@ -56,7 +56,7 @@ import Swift
5656% 'name: String? = nil',
5757% 'executorPreference taskExecutor: (any TaskExecutor)?',
5858% 'priority: TaskPriority? = nil',
59- % 'operation: sending @escaping () async throws -> Success',
59+ % 'operation: sending @escaping () async throws(Failure) -> Success',
6060% ]),
6161% # ==== --------------------------------------------------------------------
6262% ([ # METHOD_VARIANT
@@ -71,7 +71,7 @@ import Swift
7171% 'name: String? = nil',
7272% 'executorPreference taskExecutor: (any TaskExecutor)?',
7373% 'priority: TaskPriority? = nil',
74- % 'operation: sending @escaping () async throws -> Success',
74+ % 'operation: sending @escaping () async throws(Failure) -> Success',
7575% ]),
7676% # !!!! -------------------------------------------------------------------------------------------------------------
7777% # !!!! Legacy / Source Compatibility "Shims"
@@ -91,6 +91,7 @@ import Swift
9191% ],
9292% [ # PARAMS
9393% 'priority: TaskPriority? = nil',
94+ % # detach does not support typed throws, it's a legacy api for compat only
9495% '@_inheritActorContext @_implicitSelfCapture operation: __owned @Sendable @escaping @isolated(any) () async throws -> Success',
9596% ]),
9697% # ==== Legacy API: runDetached
@@ -105,6 +106,7 @@ import Swift
105106% ],
106107% [ # PARAMS
107108% 'priority: TaskPriority? = nil',
109+ % # runDetached does not support typed throws, it's a legacy api for compat only
108110% '@_inheritActorContext @_implicitSelfCapture operation: __owned @Sendable @escaping @isolated(any) () async throws -> Success',
109111% ]),
110112% # ==== Legacy API: asyncDetached
@@ -119,6 +121,7 @@ import Swift
119121% ],
120122% [ # PARAMS
121123% 'priority: TaskPriority? = nil',
124+ % # asyncDetached does not support typed throws, it's a legacy api for compat only
122125% '@_inheritActorContext @_implicitSelfCapture operation: __owned @Sendable @escaping @isolated(any) () async throws -> Success',
123126% ]),
124127% # ==== Legacy API: async
@@ -133,6 +136,7 @@ import Swift
133136% ],
134137% [ # PARAMS
135138% 'priority: TaskPriority? = nil',
139+ % # async does not support typed throws, it's a legacy api for compat only
136140% '@_inheritActorContext @_implicitSelfCapture operation: __owned @Sendable @escaping @isolated(any) () async throws -> Success',
137141% ]),
138142% ]:
@@ -149,8 +153,10 @@ import Swift
149153% HAS_ISOLATED_ANY = any('@isolated(any)' in param for param in PARAMS)
150154% IS_DEPRECATED = any('deprecated' in a for a in ALL_AVAILABILITY)
151155%
152- % if IS_THROWING:
153- % FAILURE_TYPE = 'Error'
156+ % if IS_THROWING and IS_TOP_LEVEL_FUNC:
157+ % FAILURE_TYPE = 'Error' # the legacy top-level funcs don't have a generic Failure, so we keep the un-typed throw
158+ % elif IS_THROWING:
159+ % FAILURE_TYPE = 'Failure' # use typed throws, the thrown type is Failure of the Task<_, Failure> type
154160% else:
155161% FAILURE_TYPE = 'Never'
156162% end
@@ -162,6 +168,7 @@ def adjust_params_for_kind(params):
162168 for p in params:
163169 np = p
164170 if not IS_THROWING:
171+ np = np.replace("throws(Failure)", "")
165172 np = np.replace("throws", "")
166173 res.append(np)
167174 return res
@@ -184,8 +191,12 @@ else:
184191
185192% # ====================================================================================================================
186193% if not IS_TOP_LEVEL_FUNC:
194+ % if IS_THROWING:
195+ extension Task { // throwing Failure error type
196+ % else:
187197extension Task where Failure == ${FAILURE_TYPE} {
188198% end
199+ % end
189200
190201% # --------------------------------------------------------------------------------------------------------------------
191202#if SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY
@@ -285,8 +296,10 @@ extension Task where Failure == ${FAILURE_TYPE} {
285296 /// - Returns: A reference to the task.
286297% end # IS_DEPRECATED
287298 ${"\n ".join(adjust_availability(ALL_AVAILABILITY))}
299+ % if not IS_THROWING:
288300 @discardableResult
289- public ${METHOD_VARIANT}( // Task ${METHOD_VARIANT}
301+ % end
302+ public ${METHOD_VARIANT}(
290303 ${",\n ".join(adjust_params_for_kind(PARAMS))}
291304 ) ${ARROW_RETURN_TYPE}{
292305
@@ -323,7 +336,7 @@ extension Task where Failure == ${FAILURE_TYPE} {
323336 initialTaskExecutorConsuming: taskExecutor,
324337 % end
325338 taskName: nameBytes.baseAddress!._rawValue,
326- operation: operation).0
339+ operation: operation).0 // Task ${METHOD_VARIANT}
327340 }
328341 #else // no $BuiltinCreateAsyncTaskOwnedTaskExecutor
329342 // legacy branch for the non-consuming task executor
@@ -338,7 +351,7 @@ extension Task where Failure == ${FAILURE_TYPE} {
338351 % end
339352 initialTaskExecutor: executorBuiltin,
340353 taskName: nameBytes.baseAddress!._rawValue,
341- operation: operation).0
354+ operation: operation).0 // Task ${METHOD_VARIANT}
342355 }
343356 #endif // $BuiltinCreateAsyncTaskOwnedTaskExecutor
344357 % else: # if no TASK_EXECUTOR
@@ -350,7 +363,7 @@ extension Task where Failure == ${FAILURE_TYPE} {
350363 initialSerialExecutor: builtinSerialExecutor,
351364 % end
352365 taskName: nameBytes.baseAddress!._rawValue,
353- operation: operation).0
366+ operation: operation).0 // Task ${METHOD_VARIANT}
354367 }
355368 % end # if no HAS_TASK_EXECUTOR
356369 } // let name
@@ -368,7 +381,7 @@ extension Task where Failure == ${FAILURE_TYPE} {
368381 initialSerialExecutor: builtinSerialExecutor,
369382 % end
370383 initialTaskExecutorConsuming: taskExecutor,
371- operation: operation).0
384+ operation: operation).0 // Task ${METHOD_VARIANT}
372385 #else
373386 // legacy branch for the non-consuming task executor
374387 let executorBuiltin: Builtin.Executor =
@@ -380,7 +393,7 @@ extension Task where Failure == ${FAILURE_TYPE} {
380393 initialSerialExecutor: builtinSerialExecutor,
381394 % end
382395 initialTaskExecutor: executorBuiltin,
383- operation: operation).0
396+ operation: operation).0 // Task ${METHOD_VARIANT}
384397 #endif
385398 }
386399% end # HAS_TASK_EXECUTOR
@@ -392,7 +405,7 @@ extension Task where Failure == ${FAILURE_TYPE} {
392405 % if HAS_ISOLATED_ANY:
393406 initialSerialExecutor: builtinSerialExecutor,
394407 % end
395- operation: operation).0
408+ operation: operation).0 // Task ${METHOD_VARIANT}
396409 }
397410
398411% if IS_INIT:
0 commit comments