@@ -83,6 +83,51 @@ private struct Transferring<Value>: Sendable {
83
83
self . value = value
84
84
}
85
85
}
86
+
87
+ // ⚠️ Pattern that the region based isolation checker does not understand how to check. Please file a bug
88
+ @available ( macOS 13 . 0 , iOS 16 . 0 , watchOS 9 . 0 , tvOS 16 . 0 , * )
89
+ public func withThrowingTimeout< T> (
90
+ isolation: isolated ( any Actor ) ? = #isolation,
91
+ until instant: ContinuousClock . Instant ,
92
+ tolerance: ContinuousClock . Instant . Duration ? = nil ,
93
+ body: ( ) async throws -> sending T
94
+ ) async throws -> sending T {
95
+ let transferringBody = { try await Transferring ( body ( ) ) }
96
+ typealias NonSendableClosure = ( ) async throws -> Transferring < T >
97
+ typealias SendableClosure = @Sendable ( ) async throws -> Transferring < T >
98
+ return try await withoutActuallyEscaping ( transferringBody) {
99
+ ( _ fn: @escaping NonSendableClosure ) async throws -> Transferring < T > in
100
+ let sendableFn = unsafeBitCast ( fn, to: SendableClosure . self)
101
+ return try await _withThrowingTimeout (
102
+ until: instant,
103
+ tolerance: tolerance,
104
+ body: sendableFn
105
+ )
106
+ } . value
107
+ }
108
+
109
+
110
+ @available ( macOS 13 . 0 , iOS 16 . 0 , watchOS 9 . 0 , tvOS 16 . 0 , * )
111
+ private func _withThrowingTimeout< T: Sendable > (
112
+ isolation: isolated ( any Actor ) ? = #isolation,
113
+ until instant: ContinuousClock . Instant ,
114
+ tolerance: ContinuousClock . Instant . Duration ? = nil ,
115
+ body: @Sendable @escaping ( ) async throws -> T
116
+ ) async throws -> T {
117
+ try await withThrowingTaskGroup ( of: T . self) { group in
118
+ group. addTask {
119
+ try await body ( )
120
+ }
121
+ group. addTask {
122
+ try await Task . sleep ( until: instant, tolerance: tolerance, clock: ContinuousClock ( ) )
123
+ throw TimeoutError ( timeout: 1 )
124
+ }
125
+ let success = try await group. next ( ) !
126
+ group. cancelAll ( )
127
+ return success
128
+ }
129
+ }
130
+
86
131
#else
87
132
public func withThrowingTimeout< T> (
88
133
seconds: TimeInterval ,
0 commit comments