Skip to content

Commit 7e72154

Browse files
committed
Remove _Continuation protocol and duplicate the relevant code.
1 parent d8f7f20 commit 7e72154

File tree

4 files changed

+192
-112
lines changed

4 files changed

+192
-112
lines changed

stdlib/public/Concurrency/CMakeLists.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ add_swift_target_library(swift_Concurrency ${SWIFT_STDLIB_LIBRARY_BUILD_TYPES} I
3737
Actor.cpp
3838
Actor.swift
3939
CheckedContinuation.swift
40-
ContinuationProtocol.swift
4140
GlobalExecutor.cpp
4241
AsyncIteratorProtocol.swift
4342
AsyncSequence.swift

stdlib/public/Concurrency/CheckedContinuation.swift

Lines changed: 90 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ internal final class CheckedContinuationCanary {
9595
/// of `withCheckedContinuation` or `withCheckedThrowingContinuation` should be
9696
/// enough to obtain the extra checking without further source modification in
9797
/// most circumstances.
98-
public struct CheckedContinuation<T, E: Error>: _Continuation {
98+
public struct CheckedContinuation<T, E: Error> {
9999
private let canary: CheckedContinuationCanary
100100

101101
/// Initialize a `CheckedContinuation` wrapper around an
@@ -119,6 +119,18 @@ public struct CheckedContinuation<T, E: Error>: _Continuation {
119119
function: function)
120120
}
121121

122+
/// Resume the task awaiting the continuation by having it return normally
123+
/// from its suspension point.
124+
///
125+
/// - Parameter value: The value to return from the continuation.
126+
///
127+
/// A continuation must be resumed exactly once. If the continuation has
128+
/// already been resumed through this object, then the attempt to resume
129+
/// the continuation again will trap.
130+
///
131+
/// After `resume` enqueues the task, control is immediately returned to
132+
/// the caller. The task will continue executing when its executor is
133+
/// able to reschedule it.
122134
public func resume(returning x: __owned T) {
123135
if let c: UnsafeContinuation<T, E> = canary.takeContinuation() {
124136
c.resume(returning: x)
@@ -127,6 +139,18 @@ public struct CheckedContinuation<T, E: Error>: _Continuation {
127139
}
128140
}
129141

142+
/// Resume the task awaiting the continuation by having it throw an error
143+
/// from its suspension point.
144+
///
145+
/// - Parameter error: The error to throw from the continuation.
146+
///
147+
/// A continuation must be resumed exactly once. If the continuation has
148+
/// already been resumed through this object, then the attempt to resume
149+
/// the continuation again will trap.
150+
///
151+
/// After `resume` enqueues the task, control is immediately returned to
152+
/// the caller. The task will continue executing when its executor is
153+
/// able to reschedule it.
130154
public func resume(throwing x: __owned E) {
131155
if let c: UnsafeContinuation<T, E> = canary.takeContinuation() {
132156
c.resume(throwing: x)
@@ -136,6 +160,71 @@ public struct CheckedContinuation<T, E: Error>: _Continuation {
136160
}
137161
}
138162

163+
extension CheckedContinuation {
164+
/// Resume the task awaiting the continuation by having it either
165+
/// return normally or throw an error based on the state of the given
166+
/// `Result` value.
167+
///
168+
/// - Parameter result: A value to either return or throw from the
169+
/// continuation.
170+
///
171+
/// A continuation must be resumed exactly once. If the continuation has
172+
/// already been resumed through this object, then the attempt to resume
173+
/// the continuation again will trap.
174+
///
175+
/// After `resume` enqueues the task, control is immediately returned to
176+
/// the caller. The task will continue executing when its executor is
177+
/// able to reschedule it.
178+
@_alwaysEmitIntoClient
179+
public func resume<Er: Error>(with result: Result<T, Er>) where E == Error {
180+
switch result {
181+
case .success(let val):
182+
self.resume(returning: val)
183+
case .failure(let err):
184+
self.resume(throwing: err)
185+
}
186+
}
187+
188+
/// Resume the task awaiting the continuation by having it either
189+
/// return normally or throw an error based on the state of the given
190+
/// `Result` value.
191+
///
192+
/// - Parameter result: A value to either return or throw from the
193+
/// continuation.
194+
///
195+
/// A continuation must be resumed exactly once. If the continuation has
196+
/// already been resumed through this object, then the attempt to resume
197+
/// the continuation again will trap.
198+
///
199+
/// After `resume` enqueues the task, control is immediately returned to
200+
/// the caller. The task will continue executing when its executor is
201+
/// able to reschedule it.
202+
@_alwaysEmitIntoClient
203+
public func resume(with result: Result<T, E>) {
204+
switch result {
205+
case .success(let val):
206+
self.resume(returning: val)
207+
case .failure(let err):
208+
self.resume(throwing: err)
209+
}
210+
}
211+
212+
/// Resume the task awaiting the continuation by having it return normally
213+
/// from its suspension point.
214+
///
215+
/// A continuation must be resumed exactly once. If the continuation has
216+
/// already been resumed through this object, then the attempt to resume
217+
/// the continuation again will trap.
218+
///
219+
/// After `resume` enqueues the task, control is immediately returned to
220+
/// the caller. The task will continue executing when its executor is
221+
/// able to reschedule it.
222+
@_alwaysEmitIntoClient
223+
public func resume() where T == Void {
224+
self.resume(returning: ())
225+
}
226+
}
227+
139228
public func withCheckedContinuation<T>(
140229
function: String = #function,
141230
_ body: (CheckedContinuation<T, Never>) -> Void

stdlib/public/Concurrency/ContinuationProtocol.swift

Lines changed: 0 additions & 109 deletions
This file was deleted.

stdlib/public/Concurrency/PartialAsyncTask.swift

Lines changed: 102 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ public struct PartialAsyncTask {
2222
}
2323

2424
@frozen
25-
public struct UnsafeContinuation<T, E: Error>: _Continuation {
25+
public struct UnsafeContinuation<T, E: Error> {
2626
@usableFromInline internal var context: Builtin.RawUnsafeContinuation
2727

2828
@_alwaysEmitIntoClient
@@ -34,6 +34,18 @@ public struct UnsafeContinuation<T, E: Error>: _Continuation {
3434
@_silgen_name("swift_continuation_resume")
3535
internal func _resume(returning value: __owned T)
3636

37+
/// Resume the task awaiting the continuation by having it return normally
38+
/// from its suspension point.
39+
///
40+
/// - Parameter value: The value to return from the continuation.
41+
///
42+
/// A continuation must be resumed exactly once. If the continuation has
43+
/// already been resumed through this object, then the attempt to resume
44+
/// the continuation again will result in undefined behavior.
45+
///
46+
/// After `resume` enqueues the task, control is immediately returned to
47+
/// the caller. The task will continue executing when its executor is
48+
/// able to reschedule it.
3749
@_alwaysEmitIntoClient
3850
public func resume(returning value: __owned T) where E == Never {
3951
self._resume(returning: value)
@@ -43,6 +55,18 @@ public struct UnsafeContinuation<T, E: Error>: _Continuation {
4355
@_silgen_name("swift_continuation_throwingResume")
4456
internal func _resume(returningToThrowingFunction: __owned T)
4557

58+
/// Resume the task awaiting the continuation by having it return normally
59+
/// from its suspension point.
60+
///
61+
/// - Parameter value: The value to return from the continuation.
62+
///
63+
/// A continuation must be resumed exactly once. If the continuation has
64+
/// already been resumed through this object, then the attempt to resume
65+
/// the continuation again will result in undefined behavior.
66+
///
67+
/// After `resume` enqueues the task, control is immediately returned to
68+
/// the caller. The task will continue executing when its executor is
69+
/// able to reschedule it.
4670
@_alwaysEmitIntoClient
4771
public func resume(returning value: __owned T) {
4872
self._resume(returningToThrowingFunction: value)
@@ -52,12 +76,89 @@ public struct UnsafeContinuation<T, E: Error>: _Continuation {
5276
@_silgen_name("swift_continuation_throwingResumeWithError")
5377
internal func _resume(throwing: __owned Error)
5478

79+
/// Resume the task awaiting the continuation by having it throw an error
80+
/// from its suspension point.
81+
///
82+
/// - Parameter error: The error to throw from the continuation.
83+
///
84+
/// A continuation must be resumed exactly once. If the continuation has
85+
/// already been resumed through this object, then the attempt to resume
86+
/// the continuation again will result in undefined behavior.
87+
///
88+
/// After `resume` enqueues the task, control is immediately returned to
89+
/// the caller. The task will continue executing when its executor is
90+
/// able to reschedule it.
5591
@_alwaysEmitIntoClient
5692
public func resume(throwing error: __owned E) {
5793
self._resume(throwing: error)
5894
}
5995
}
6096

97+
extension UnsafeContinuation {
98+
/// Resume the task awaiting the continuation by having it either
99+
/// return normally or throw an error based on the state of the given
100+
/// `Result` value.
101+
///
102+
/// - Parameter result: A value to either return or throw from the
103+
/// continuation.
104+
///
105+
/// A continuation must be resumed exactly once. If the continuation has
106+
/// already been resumed through this object, then the attempt to resume
107+
/// the continuation again will trap.
108+
///
109+
/// After `resume` enqueues the task, control is immediately returned to
110+
/// the caller. The task will continue executing when its executor is
111+
/// able to reschedule it.
112+
@_alwaysEmitIntoClient
113+
public func resume<Er: Error>(with result: Result<T, Er>) where E == Error {
114+
switch result {
115+
case .success(let val):
116+
self.resume(returning: val)
117+
case .failure(let err):
118+
self.resume(throwing: err)
119+
}
120+
}
121+
122+
/// Resume the task awaiting the continuation by having it either
123+
/// return normally or throw an error based on the state of the given
124+
/// `Result` value.
125+
///
126+
/// - Parameter result: A value to either return or throw from the
127+
/// continuation.
128+
///
129+
/// A continuation must be resumed exactly once. If the continuation has
130+
/// already been resumed through this object, then the attempt to resume
131+
/// the continuation again will trap.
132+
///
133+
/// After `resume` enqueues the task, control is immediately returned to
134+
/// the caller. The task will continue executing when its executor is
135+
/// able to reschedule it.
136+
@_alwaysEmitIntoClient
137+
public func resume(with result: Result<T, E>) {
138+
switch result {
139+
case .success(let val):
140+
self.resume(returning: val)
141+
case .failure(let err):
142+
self.resume(throwing: err)
143+
}
144+
}
145+
146+
/// Resume the task awaiting the continuation by having it return normally
147+
/// from its suspension point.
148+
///
149+
/// A continuation must be resumed exactly once. If the continuation has
150+
/// already been resumed through this object, then the attempt to resume
151+
/// the continuation again will trap.
152+
///
153+
/// After `resume` enqueues the task, control is immediately returned to
154+
/// the caller. The task will continue executing when its executor is
155+
/// able to reschedule it.
156+
@_alwaysEmitIntoClient
157+
public func resume() where T == Void {
158+
self.resume(returning: ())
159+
}
160+
}
161+
61162
#if _runtime(_ObjC)
62163

63164
// Intrinsics used by SILGen to resume or fail continuations.

0 commit comments

Comments
 (0)