Skip to content

Commit c5a77fc

Browse files
committed
Add a proper TaskGroup.Iterator.next(isolation:)
Implement this function to pass the isolation through to the task group's `next(isolation:)`. Fixes rdar://129690995.
1 parent e431216 commit c5a77fc

File tree

2 files changed

+36
-3
lines changed

2 files changed

+36
-3
lines changed

stdlib/public/Concurrency/TaskGroup.swift

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1211,6 +1211,29 @@ extension TaskGroup: AsyncSequence {
12111211
return element
12121212
}
12131213

1214+
/// Advances to and returns the result of the next child task.
1215+
///
1216+
/// The elements returned from this method
1217+
/// appear in the order that the tasks *completed*,
1218+
/// not in the order that those tasks were added to the task group.
1219+
/// After this method returns `nil`,
1220+
/// this iterator is guaranteed to never produce more values.
1221+
///
1222+
/// For more information about the iteration order and semantics,
1223+
/// see `TaskGroup.next()`.
1224+
///
1225+
/// - Returns: The value returned by the next child task that completes,
1226+
/// or `nil` if there are no remaining child tasks,
1227+
@available(SwiftStdlib 6.0, *)
1228+
public mutating func next(isolation actor: isolated (any Actor)?) async -> Element? {
1229+
guard !finished else { return nil }
1230+
guard let element = await group.next(isolation: actor) else {
1231+
finished = true
1232+
return nil
1233+
}
1234+
return element
1235+
}
1236+
12141237
public mutating func cancel() {
12151238
finished = true
12161239
group.cancelAll()
@@ -1324,7 +1347,7 @@ extension ThrowingTaskGroup: AsyncSequence {
13241347
public mutating func next(isolation actor: isolated (any Actor)?) async throws(Failure) -> Element? {
13251348
guard !finished else { return nil }
13261349
do {
1327-
guard let element = try await group.next() else {
1350+
guard let element = try await group.next(isolation: actor) else {
13281351
finished = true
13291352
return nil
13301353
}

test/Concurrency/async_sequence_macosx.swift

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %target-swift-frontend -target %target-cpu-apple-macos14.0 %s -emit-sil -o /dev/null -verify
1+
// RUN: %target-swift-frontend -target %target-cpu-apple-macos14.0 %s -emit-sil -o /dev/null -verify -swift-version 6
22

33
// REQUIRES: concurrency, OS=macosx
44

@@ -15,4 +15,14 @@ func f<S: AsyncSequence>(s: S) async throws {
1515
}
1616
}
1717

18-
18+
// Make sure we don't complain about crossing a concurrency boundary here.
19+
@MainActor
20+
class Store<Action: Sendable> {
21+
private func intercept(_ action: Action) async {
22+
await withTaskGroup(of: Optional<Action>.self) { group in
23+
for await case let nextAction? in group {
24+
_ = nextAction
25+
}
26+
}
27+
}
28+
}

0 commit comments

Comments
 (0)