Skip to content

Commit f5d0abc

Browse files
Support typed throws (#52)
* Support typed throws * Update Sources/ConcurrencyExtras/Result.swift Co-authored-by: Stephen Celis <[email protected]> * Constrain change to compiler(>=6) * Also gate the test to Swift 6 * Include func g in ifdef * wip --------- Co-authored-by: Stephen Celis <[email protected]> Co-authored-by: Stephen Celis <[email protected]>
1 parent d1e4642 commit f5d0abc

File tree

2 files changed

+87
-12
lines changed

2 files changed

+87
-12
lines changed
+25-12
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,27 @@
1-
extension Result where Failure == Swift.Error {
2-
/// Creates a new result by evaluating an async throwing closure, capturing the returned value as
3-
/// a success, or any thrown error as a failure.
4-
///
5-
/// - Parameter body: A throwing closure to evaluate.
6-
@_transparent
7-
public init(catching body: () async throws -> Success) async {
8-
do {
9-
self = .success(try await body())
10-
} catch {
11-
self = .failure(error)
1+
#if compiler(>=6)
2+
extension Result {
3+
/// Creates a new result by evaluating an async throwing closure, capturing the returned value as
4+
/// a success, or any thrown error as a failure.
5+
///
6+
/// - Parameter body: A throwing closure to evaluate.
7+
@_transparent
8+
public init(catching body: () async throws(Failure) -> Success) async {
9+
do {
10+
self = .success(try await body())
11+
} catch {
12+
self = .failure(error)
13+
}
1214
}
1315
}
14-
}
16+
#else
17+
extension Result where Failure == Swift.Error {
18+
@_transparent
19+
public init(catching body: () async throws -> Success) async {
20+
do {
21+
self = .success(try await body())
22+
} catch {
23+
self = .failure(error)
24+
}
25+
}
26+
}
27+
#endif
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import ConcurrencyExtras
2+
import XCTest
3+
4+
final class ResultTests: XCTestCase {
5+
struct SomeError: Error, Equatable { }
6+
func f(_ value: Int) async throws -> Int {
7+
if value == 42 {
8+
return 42
9+
} else {
10+
throw SomeError()
11+
}
12+
}
13+
14+
func testBasics() async {
15+
do {
16+
let res = await Result { try await f(42) }
17+
XCTAssertEqual(try res.get(), 42)
18+
}
19+
do {
20+
let res = await Result { try await f(0) }
21+
do {
22+
_ = try res.get()
23+
} catch let error as SomeError {
24+
XCTAssertEqual(error, SomeError())
25+
} catch {
26+
XCTFail("unexpected error: \(error)")
27+
}
28+
}
29+
}
30+
31+
#if compiler(>=6)
32+
func g(_ value: Int) async throws(SomeError) -> Int {
33+
if value == 42 {
34+
return 42
35+
} else {
36+
throw SomeError()
37+
}
38+
}
39+
40+
func testTypedThrows() async {
41+
let res = await Result { () async throws(SomeError) -> Int in try await g(0) }
42+
do {
43+
_ = try res.get()
44+
} catch {
45+
XCTAssertEqual(error, SomeError())
46+
}
47+
}
48+
49+
func h() async throws(SomeError) -> Int {
50+
throw SomeError()
51+
}
52+
53+
func testTypedThrowsInference() async {
54+
let res = await Result(catching: h)
55+
do {
56+
_ = try res.get()
57+
} catch {
58+
XCTAssertEqual(error, SomeError())
59+
}
60+
}
61+
#endif
62+
}

0 commit comments

Comments
 (0)