Skip to content

Commit 6b1b6f5

Browse files
fix: restore generic Failure
1 parent 38e635e commit 6b1b6f5

File tree

4 files changed

+81
-53
lines changed

4 files changed

+81
-53
lines changed

Package.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import CompilerPluginSupport
66
let AsyncAlgorithms_v1_0 = "AvailabilityMacro=AsyncAlgorithms 1.0:macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0"
77
#if compiler(>=6.0) && swift(>=6.0) // 5.10 doesnt support visionOS availability
88
let AsyncAlgorithms_v1_1 =
9-
"AvailabilityMacro=AsyncAlgorithms 1.1:macOS 15.0, iOS 18.0, tvOS 18.0, watchOS 11.0, visionOS 2.0"
9+
"AvailabilityMacro=AsyncAlgorithms 1.1:macOS 13.0, iOS 16.0, tvOS 16.0, watchOS 9.0, visionOS 1.0"
1010
#else
1111
let AsyncAlgorithms_v1_1 = "AvailabilityMacro=AsyncAlgorithms 1.1:macOS 15.0, iOS 18.0, tvOS 18.0, watchOS 11.0"
1212
#endif

Sources/AsyncAlgorithms/AsyncShareSequence.swift

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
import Synchronization
1313
import DequeModule
1414

15-
@available(AsyncAlgorithms 1.0, *)
15+
@available(AsyncAlgorithms 1.1, *)
1616
extension AsyncSequence
1717
where Element: Sendable, Self: _SendableMetatype, AsyncIterator: _SendableMetatype {
1818
/// Creates a shared async sequence that allows multiple concurrent iterations over a single source.
@@ -112,7 +112,7 @@ where Element: Sendable, Self: _SendableMetatype, AsyncIterator: _SendableMetaty
112112
//
113113
// This type is typically not used directly; instead, use the `share()` method on any
114114
// async sequence that meets the sendability requirements.
115-
@available(AsyncAlgorithms 1.0, *)
115+
@available(AsyncAlgorithms 1.1, *)
116116
public struct AsyncShareSequence<Base: AsyncSequence>: Sendable
117117
where Base.Element: Sendable, Base: _SendableMetatype, Base.AsyncIterator: _SendableMetatype {
118118
// Represents a single consumer's connection to the shared sequence.
@@ -133,7 +133,7 @@ where Base.Element: Sendable, Base: _SendableMetatype, Base.AsyncIterator: _Send
133133
// - `continuation`: The continuation waiting for the next element (nil if not waiting)
134134
// - `position`: The consumer's current position in the shared buffer
135135
struct State {
136-
var continuation: UnsafeContinuation<Result<Base.Element?, Error>, Never>?
136+
var continuation: UnsafeContinuation<Result<Base.Element?, _Failure>, Never>?
137137
var position = 0
138138

139139
// Creates a new state with the position adjusted by the given offset.
@@ -160,7 +160,7 @@ where Base.Element: Sendable, Base: _SendableMetatype, Base.AsyncIterator: _Send
160160
iteration.unregisterSide(id)
161161
}
162162

163-
func next(isolation actor: isolated (any Actor)?) async throws -> Base.Element? {
163+
func next(isolation actor: isolated (any Actor)?) async throws(Failure) -> Base.Element? {
164164
try await iteration.next(isolation: actor, id: id)
165165
}
166166
}
@@ -230,7 +230,7 @@ where Base.Element: Sendable, Base: _SendableMetatype, Base.AsyncIterator: _Send
230230
var iteratingTask: IteratingTask
231231
private(set) var buffer = Deque<Base.Element>()
232232
private(set) var finished = false
233-
private(set) var failure: Error?
233+
private(set) var failure: Failure?
234234
var cancelled = false
235235
var limit: UnsafeContinuation<Bool, Never>?
236236
var demand: UnsafeContinuation<Void, Never>?
@@ -333,7 +333,7 @@ where Base.Element: Sendable, Base: _SendableMetatype, Base.AsyncIterator: _Send
333333
finished = true
334334
}
335335

336-
mutating func fail(_ error: Error) {
336+
mutating func fail(_ error: Failure) {
337337
finished = true
338338
failure = error
339339
}
@@ -476,15 +476,15 @@ where Base.Element: Sendable, Base: _SendableMetatype, Base.AsyncIterator: _Send
476476
}
477477

478478
struct Resumption {
479-
let continuation: UnsafeContinuation<Result<Base.Element?, Error>, Never>
480-
let result: Result<Base.Element?, Error>
479+
let continuation: UnsafeContinuation<Result<Base.Element?, Failure>, Never>
480+
let result: Result<Base.Element?, Failure>
481481

482482
func resume() {
483483
continuation.resume(returning: result)
484484
}
485485
}
486486

487-
func emit(_ result: Result<Base.Element?, Error>) {
487+
func emit(_ result: Result<Base.Element?, Failure>) {
488488
let (resumptions, limitContinuation, demandContinuation, cancelled) = state.withLock {
489489
state -> ([Resumption], UnsafeContinuation<Bool, Never>?, UnsafeContinuation<Void, Never>?, Bool) in
490490
var resumptions = [Resumption]()
@@ -531,12 +531,12 @@ where Base.Element: Sendable, Base: _SendableMetatype, Base.AsyncIterator: _Send
531531

532532
private func nextIteration(
533533
_ id: Int
534-
) async -> Result<Base.Element?, Error> {
534+
) async -> Result<Base.Element?, Failure> {
535535
return await withTaskCancellationHandler {
536536
await withUnsafeContinuation { continuation in
537537
let (res, limitContinuation, demandContinuation, cancelled) = state.withLock {
538538
state -> (
539-
Result<Base.Element?, Error>?, UnsafeContinuation<Bool, Never>?, UnsafeContinuation<Void, Never>?, Bool
539+
Result<Base.Element?, Failure>?, UnsafeContinuation<Bool, Never>?, UnsafeContinuation<Void, Never>?, Bool
540540
) in
541541
guard let side = state.sides[id] else {
542542
return state.emit(.success(nil), limit: limit)
@@ -589,7 +589,7 @@ where Base.Element: Sendable, Base: _SendableMetatype, Base.AsyncIterator: _Send
589589
}
590590
}
591591

592-
func next(isolation actor: isolated (any Actor)?, id: Int) async throws -> Base.Element? {
592+
func next(isolation actor: isolated (any Actor)?, id: Int) async rethrows -> Base.Element? {
593593
let iteratingTask = state.withLock { state -> IteratingTask in
594594
defer {
595595
if case .pending = state.iteratingTask {
@@ -693,10 +693,9 @@ where Base.Element: Sendable, Base: _SendableMetatype, Base.AsyncIterator: _Send
693693
}
694694
}
695695

696-
@available(AsyncAlgorithms 1.0, *)
697-
extension AsyncShareSequence: AsyncSequence {
696+
@available(AsyncAlgorithms 1.1, *)
697+
extension AsyncShareSequence: AsyncSequence, FailableAsyncSequence {
698698
public typealias Element = Base.Element
699-
public typealias Failure = Swift.Error
700699

701700
public struct Iterator: AsyncIteratorProtocol {
702701
let side: Side
@@ -709,7 +708,7 @@ extension AsyncShareSequence: AsyncSequence {
709708
try await side.next(isolation: nil)
710709
}
711710

712-
mutating public func next(isolation actor: isolated (any Actor)?) async throws(Failure) -> Element? {
711+
mutating public func next(isolation actor: isolated (any Actor)?) async rethrows -> Element? {
713712
try await side.next(isolation: actor)
714713
}
715714
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift Async Algorithms open source project
4+
//
5+
// Copyright (c) 2022 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+
//
10+
//===----------------------------------------------------------------------===//
11+
12+
/// A backportable protocol / hack to allow `Failure` associated type on older iOS/macOS/etc. versions.
13+
///
14+
/// By assigning this protocol to any value conforming to `AsyncSequence`, they will both have access to `Failure`
15+
/// > There could be a possible issue with mangled name of the entire object as discussed
16+
/// [here](https://forums.swift.org/t/how-to-use-asyncsequence-on-macos-14-5-in-xcode-16-beta-need-help-with-availability-check-since-failure-is-unavailb-e/72439/5).
17+
/// However, the issue should only happen if the object conforming to this protocol follows (_Concurrency, AsyncSequence)
18+
/// in lexicographic order. (AsyncAlgorithms, MySequence) should always be after it.
19+
///
20+
/// Example:
21+
/// ```swift
22+
/// class MySequence: AsyncSequence, FailableAsyncSequence { ... }
23+
///
24+
/// ```
25+
@available(AsyncAlgorithms 1.1, *)
26+
public protocol FailableAsyncSequence {
27+
typealias _Failure = Failure
28+
associatedtype Failure: Error
29+
}

0 commit comments

Comments
 (0)