Skip to content

Commit eda5b4d

Browse files
committed
[Concurrency] Alternative Task API.
The `Task` type has oscillated somewhat from being purely a namespace, to having instances that are used (albeit rarely), back to purely being a namespace that isn't used for all that many names. Many of the names that used to be on Task have already been moved out, e.g., for creating new detached tasks, creating new task groups, adding cancellation handlers, etc. Collapse `Task.Handle<Success, Failure>` into `Task<Success, Failure>`. `Task.Handle` is the type that is most frequently referenced in the concurrency library, so giving it the short name `Task` is most appropriate. Replace the top-level async/detach functions with a `Task` initializer and `Task.detached`, respectively. The `Task` type can still act as a namespace for static operations such as, e.g., `Task.isCancelled`. Do this with an extension of the form: extension Task where Success == Never, Failure == Never { ... } We've been accruing a number of compatibility shims. Move them all into their own source file, deprecate them, and make them always-emit-into-client so they don't have any ABI impact.
1 parent a8fa551 commit eda5b4d

17 files changed

+764
-661
lines changed

stdlib/public/Concurrency/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ add_swift_target_library(swift_Concurrency ${SWIFT_STDLIB_LIBRARY_BUILD_TYPES} I
6161
AsyncThrowingMapSequence.swift
6262
AsyncThrowingPrefixWhileSequence.swift
6363
PartialAsyncTask.swift
64+
SourceCompatibilityShims.swift
6465
Task.cpp
6566
Task.swift
6667
TaskCancellation.swift

stdlib/public/Concurrency/PartialAsyncTask.swift

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,3 @@ public func withUnsafeThrowingContinuation<T>(
223223
fn(UnsafeContinuation<T, Error>($0))
224224
}
225225
}
226-
227-
@available(SwiftStdlib 5.5, *)
228-
@available(*, deprecated, message: "please use UnsafeContination<..., Error>")
229-
public typealias UnsafeThrowingContinuation<T> = UnsafeContinuation<T, Error>
Lines changed: 209 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2020 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
// This file provides source compatibility shims to help migrate code
13+
// using earlier versions of the concurrency library to the latest syntax.
14+
//===----------------------------------------------------------------------===//
15+
16+
import Swift
17+
@_implementationOnly import _SwiftConcurrencyShims
18+
19+
@available(SwiftStdlib 5.5, *)
20+
extension Task where Success == Never, Failure == Never {
21+
@available(*, deprecated, message: "use TaskPriority")
22+
public typealias Priority = TaskPriority
23+
24+
@available(*, deprecated, message: "use Task")
25+
public typealias Handle = _Concurrency.Task
26+
}
27+
28+
@available(SwiftStdlib 5.5, *)
29+
extension TaskPriority {
30+
@available(*, deprecated, message: "unspecified priority will be removed; use nil")
31+
public static let unspecified: TaskPriority = .init(rawValue: 0x00)
32+
}
33+
34+
@available(SwiftStdlib 5.5, *)
35+
extension Task where Success == Never, Failure == Never {
36+
@available(*, deprecated, message: "`Task.withCancellationHandler` has been replaced by `withTaskCancellationHandler` and will be removed shortly.")
37+
@_alwaysEmitIntoClient
38+
public static func withCancellationHandler<T>(
39+
handler: @Sendable () -> (),
40+
operation: () async throws -> T
41+
) async rethrows -> T {
42+
try await withTaskCancellationHandler(handler: handler, operation: operation)
43+
}
44+
}
45+
46+
@available(SwiftStdlib 5.5, *)
47+
extension Task where Failure == Error {
48+
@discardableResult
49+
@_alwaysEmitIntoClient
50+
@available(*, deprecated, message: "`Task.runDetached` was replaced by `Task.detached` and will be removed shortly.")
51+
public static func runDetached(
52+
priority: TaskPriority = .unspecified,
53+
operation: __owned @Sendable @escaping () async throws -> Success
54+
) -> Task<Success, Failure> {
55+
detached(priority: priority, operation: operation)
56+
}
57+
}
58+
59+
@discardableResult
60+
@available(SwiftStdlib 5.5, *)
61+
@available(*, deprecated, message: "`detach` was replaced by `Task.detached` and will be removed shortly.")
62+
@_alwaysEmitIntoClient
63+
public func detach<T>(
64+
priority: TaskPriority? = nil,
65+
operation: __owned @Sendable @escaping () async -> T
66+
) -> Task<T, Never> {
67+
Task.detached(priority: priority, operation: operation)
68+
}
69+
70+
@discardableResult
71+
@available(SwiftStdlib 5.5, *)
72+
@available(*, deprecated, message: "`detach` was replaced by `Task.detached` and will be removed shortly.")
73+
@_alwaysEmitIntoClient
74+
public func detach<T>(
75+
priority: TaskPriority? = nil,
76+
operation: __owned @Sendable @escaping () async throws -> T
77+
) -> Task<T, Error> {
78+
Task.detached(priority: priority, operation: operation)
79+
}
80+
81+
@discardableResult
82+
@available(SwiftStdlib 5.5, *)
83+
@available(*, deprecated, message: "`asyncDetached` was replaced by `Task.detached` and will be removed shortly.")
84+
@_alwaysEmitIntoClient
85+
public func asyncDetached<T>(
86+
priority: TaskPriority? = nil,
87+
@_implicitSelfCapture operation: __owned @Sendable @escaping () async -> T
88+
) -> Task<T, Never> {
89+
return Task.detached(priority: priority, operation: operation)
90+
}
91+
92+
@discardableResult
93+
@available(SwiftStdlib 5.5, *)
94+
@available(*, deprecated, message: "`asyncDetached` was replaced by `Task.detached` and will be removed shortly.")
95+
@_alwaysEmitIntoClient
96+
public func asyncDetached<T>(
97+
priority: TaskPriority? = nil,
98+
@_implicitSelfCapture operation: __owned @Sendable @escaping () async throws -> T
99+
) -> Task<T, Error> {
100+
return Task.detached(priority: priority, operation: operation)
101+
}
102+
103+
@available(SwiftStdlib 5.5, *)
104+
@available(*, deprecated, message: "`async` was replaced by `Task.init` and will be removed shortly.")
105+
@discardableResult
106+
@_alwaysEmitIntoClient
107+
public func async<T>(
108+
priority: TaskPriority? = nil,
109+
@_inheritActorContext @_implicitSelfCapture operation: __owned @Sendable @escaping () async -> T
110+
) -> Task<T, Never> {
111+
.init(priority: priority, operation: operation)
112+
}
113+
114+
@available(SwiftStdlib 5.5, *)
115+
@available(*, deprecated, message: "`async` was replaced by `Task.init` and will be removed shortly.")
116+
@discardableResult
117+
@_alwaysEmitIntoClient
118+
public func async<T>(
119+
priority: TaskPriority? = nil,
120+
@_inheritActorContext @_implicitSelfCapture operation: __owned @Sendable @escaping () async throws -> T
121+
) -> Task<T, Error> {
122+
.init(priority: priority, operation: operation)
123+
}
124+
125+
@available(SwiftStdlib 5.5, *)
126+
extension Task where Success == Never, Failure == Never {
127+
@available(*, deprecated, message: "`Task.Group` was replaced by `ThrowingTaskGroup` and `TaskGroup` and will be removed shortly.")
128+
public typealias Group<TaskResult> = ThrowingTaskGroup<TaskResult, Error>
129+
130+
@available(*, deprecated, message: "`Task.withGroup` was replaced by `withThrowingTaskGroup` and `withTaskGroup` and will be removed shortly.")
131+
@_alwaysEmitIntoClient
132+
public static func withGroup<TaskResult, BodyResult>(
133+
resultType: TaskResult.Type,
134+
returning returnType: BodyResult.Type = BodyResult.self,
135+
body: (inout Task.Group<TaskResult>) async throws -> BodyResult
136+
) async rethrows -> BodyResult {
137+
try await withThrowingTaskGroup(of: resultType) { group in
138+
try await body(&group)
139+
}
140+
}
141+
}
142+
143+
@available(SwiftStdlib 5.5, *)
144+
extension TaskGroup {
145+
@available(*, deprecated, renamed: "async(priority:operation:)")
146+
@_alwaysEmitIntoClient
147+
public mutating func add(
148+
priority: TaskPriority? = nil,
149+
operation: __owned @Sendable @escaping () async -> ChildTaskResult
150+
) async -> Bool {
151+
return self.asyncUnlessCancelled(priority: priority) {
152+
await operation()
153+
}
154+
}
155+
156+
@available(*, deprecated, renamed: "async(priority:operation:)")
157+
@_alwaysEmitIntoClient
158+
public mutating func spawn(
159+
priority: TaskPriority? = nil,
160+
operation: __owned @Sendable @escaping () async -> ChildTaskResult
161+
) {
162+
async(priority: priority, operation: operation)
163+
}
164+
165+
@available(*, deprecated, renamed: "asyncUnlessCancelled(priority:operation:)")
166+
@_alwaysEmitIntoClient
167+
public mutating func spawnUnlessCancelled(
168+
priority: TaskPriority? = nil,
169+
operation: __owned @Sendable @escaping () async -> ChildTaskResult
170+
) -> Bool {
171+
asyncUnlessCancelled(priority: priority, operation: operation)
172+
}
173+
}
174+
175+
@available(SwiftStdlib 5.5, *)
176+
extension ThrowingTaskGroup {
177+
@available(*, deprecated, renamed: "async(priority:operation:)")
178+
@_alwaysEmitIntoClient
179+
public mutating func add(
180+
priority: TaskPriority? = nil,
181+
operation: __owned @Sendable @escaping () async throws -> ChildTaskResult
182+
) async -> Bool {
183+
return self.asyncUnlessCancelled(priority: priority) {
184+
try await operation()
185+
}
186+
}
187+
188+
@available(*, deprecated, renamed: "async(priority:operation:)")
189+
@_alwaysEmitIntoClient
190+
public mutating func spawn(
191+
priority: TaskPriority? = nil,
192+
operation: __owned @Sendable @escaping () async throws -> ChildTaskResult
193+
) {
194+
async(priority: priority, operation: operation)
195+
}
196+
197+
@available(*, deprecated, renamed: "asyncUnlessCancelled(priority:operation:)")
198+
@_alwaysEmitIntoClient
199+
public mutating func spawnUnlessCancelled(
200+
priority: TaskPriority? = nil,
201+
operation: __owned @Sendable @escaping () async throws -> ChildTaskResult
202+
) -> Bool {
203+
asyncUnlessCancelled(priority: priority, operation: operation)
204+
}
205+
}
206+
207+
@available(SwiftStdlib 5.5, *)
208+
@available(*, deprecated, message: "please use UnsafeContination<..., Error>")
209+
public typealias UnsafeThrowingContinuation<T> = UnsafeContinuation<T, Error>

0 commit comments

Comments
 (0)