Skip to content

Commit 31144b9

Browse files
natecook1000ktoso
authored andcommitted
Test for Update TaskGroup iterator semantics to match proposal
This modifies TaskGroup.Iterator so that it doesn't continue returning elements after throwing. This is a more restricted behavior than TaskGroup.next(), which keeps returning elements or throwing errors until all tasks have been consumed.
1 parent 6e74630 commit 31144b9

File tree

1 file changed

+121
-0
lines changed

1 file changed

+121
-0
lines changed
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
// RUN: %target-run-simple-swift(-Xfrontend -enable-experimental-concurrency -parse-as-library) | %FileCheck %s --dump-input=always
2+
// REQUIRES: executable_test
3+
// REQUIRES: concurrency
4+
// XFAIL: linux
5+
// XFAIL: windows
6+
struct Boom: Error {}
7+
8+
func boom() async throws -> Int {
9+
throw Boom()
10+
}
11+
12+
func test_taskGroup_next() async {
13+
let sum: Int = await Task.withGroup(resultType: Int.self) { group in
14+
for n in 1...10 {
15+
await group.add {
16+
return n.isMultiple(of: 3)
17+
? try await boom()
18+
: n
19+
}
20+
}
21+
22+
var sum = 0
23+
var catches = 0
24+
for _ in 1...5 {
25+
do {
26+
while let r = try await group.next() {
27+
sum += r
28+
}
29+
} catch {
30+
catches += 1
31+
}
32+
}
33+
34+
// CHECK: catches with group.next(): 3
35+
print("catches with group.next(): \(catches)")
36+
37+
return sum
38+
}
39+
40+
// CHECK: result with group.next(): 37
41+
print("result with group.next(): \(sum)")
42+
}
43+
44+
func test_taskGroup_for_in() async {
45+
let sum: Int = await Task.withGroup(resultType: Int.self) { group in
46+
for n in 1...10 {
47+
await group.add {
48+
return n.isMultiple(of: 3)
49+
? try await boom()
50+
: n
51+
}
52+
}
53+
54+
var sum = 0
55+
var catches = 0
56+
for _ in 1...5 {
57+
do {
58+
for try await r in group {
59+
sum += r
60+
}
61+
} catch {
62+
catches += 1
63+
}
64+
}
65+
66+
// CHECK: catches with for-in: 3
67+
print("catches with for-in: \(catches)")
68+
69+
return sum
70+
}
71+
72+
// CHECK: result with for-in: 37
73+
print("result with for-in: \(sum)")
74+
}
75+
76+
func test_taskGroup_asyncIterator() async {
77+
let sum: Int = await Task.withGroup(resultType: Int.self) { group in
78+
for n in 1...10 {
79+
await group.add {
80+
return n.isMultiple(of: 3)
81+
? try await boom()
82+
: n
83+
}
84+
}
85+
86+
var sum = 0
87+
var catches = 0
88+
for _ in 1...5 {
89+
var iterator = group.makeAsyncIterator()
90+
do {
91+
while let r = try await iterator.next() {
92+
sum += r
93+
}
94+
if try! await iterator.next() != nil {
95+
fatalError("Element returned from iterator after nil")
96+
}
97+
} catch {
98+
catches += 1
99+
if try! await iterator.next() != nil {
100+
fatalError("Element returned from iterator after throw")
101+
}
102+
}
103+
}
104+
105+
// CHECK: catches with for-in: 3
106+
print("catches with for-in: \(catches)")
107+
108+
return sum
109+
}
110+
111+
// CHECK: result with async iterator: 37
112+
print("result with async iterator: \(sum)")
113+
}
114+
115+
@main struct Main {
116+
static func main() async {
117+
await test_taskGroup_next()
118+
await test_taskGroup_for_in()
119+
await test_taskGroup_asyncIterator()
120+
}
121+
}

0 commit comments

Comments
 (0)