@@ -30,42 +30,44 @@ accidentally unwrapping a `nil` value.
30
30
31
31
For example:
32
32
33
- ```swift
34
- func doWork() throws -> Result {
35
- var result: Result? = nil
36
- var error: ErrorProtocol? = nil
37
- autoreleasepool {
38
- do {
39
- ... actual computation which hopefully assigns to result but might not ...
40
- } catch let e {
41
- error = e
42
- }
33
+ ``` swift
34
+ func doWork () throws -> Result {
35
+ var result: Result? = nil
36
+ var error: ErrorProtocol? = nil
37
+ autoreleasepool {
38
+ do {
39
+ ... actual computation which hopefully assigns to result but might not ...
40
+ } catch let e {
41
+ error = e
43
42
}
44
- guard let result = result else {
45
- throw error!
46
- }
47
- return result!
48
43
}
49
- ```
44
+ guard let result = result else {
45
+ throw error!
46
+ }
47
+ return result!
48
+ }
49
+ ```
50
50
51
51
## Proposed solution
52
52
53
53
I'd like to propose altering the signature of the standard library
54
54
` autoreleasepool ` function to allow for a generic return type, as well as
55
55
allowing a ` throw ` of an error:
56
56
57
- public func autoreleasepool<Result>(@noescape body: () throws -> Result) rethrows -> Result
57
+ ``` swift
58
+ public func autoreleasepool <Result >(@noescape body : () throws -> Result) rethrows -> Result
59
+ ```
58
60
59
61
The case above becomes much more clear and less error-prone since the compiler
60
62
can enforce that exactly one of the error and result are used:
61
63
62
- ```swift
63
- func doWork() throws -> Result {
64
- return try autoreleasepool {
65
- ... actual computation which either returns or throws ...
66
- }
64
+ ``` swift
65
+ func doWork () throws -> Result {
66
+ return try autoreleasepool {
67
+ ... actual computation which either returns or throws ...
67
68
}
68
- ```
69
+ }
70
+ ```
69
71
70
72
As an aside, since this proposes changing the signature already, I would like
71
73
to further propose changing the argument label from ` code ` to ` body ` . This seems
@@ -76,15 +78,15 @@ but isn't central to this proposal.
76
78
77
79
The updated standard library function would read:
78
80
79
- ```swift
80
- public func autoreleasepool<Result>(@noescape body: () throws -> Result) rethrows -> Result {
81
- let pool = __pushAutoreleasePool()
82
- defer {
83
- __popAutoreleasePool(pool)
84
- }
85
- return try body()
81
+ ``` swift
82
+ public func autoreleasepool <Result >(@noescape body : () throws -> Result) rethrows -> Result {
83
+ let pool = __pushAutoreleasePool ()
84
+ defer {
85
+ __popAutoreleasePool (pool)
86
86
}
87
- ```
87
+ return try body ()
88
+ }
89
+ ```
88
90
89
91
## Impact on existing code
90
92
@@ -99,26 +101,26 @@ return type would be better.
99
101
I also explored whether third-party code could wrap ` autoreleasepool ` themselves
100
102
with something like:
101
103
102
- ```swift
103
- func autoreleasepool_generic<ResultType>(@noescape code: Void throws -> ResultType) rethrows -> ResultType {
104
- var result:ResultType?
105
- var error:ErrorProtocol?
106
-
107
- autoreleasepool {
108
- do {
109
- result = try code()
110
- } catch let e {
111
- error = e
112
- }
113
- }
114
-
115
- if let result = result {
116
- return result
104
+ ``` swift
105
+ func autoreleasepool_generic <ResultType >(@noescape code : Void throws -> ResultType) rethrows -> ResultType {
106
+ var result:ResultType?
107
+ var error:ErrorProtocol?
108
+
109
+ autoreleasepool {
110
+ do {
111
+ result = try code ()
112
+ } catch let e {
113
+ error = e
117
114
}
118
-
119
- throw error! // Doesn't compile.
120
115
}
121
- ```
116
+
117
+ if let result = result {
118
+ return result
119
+ }
120
+
121
+ throw error! // Doesn't compile.
122
+ }
123
+ ```
122
124
123
125
but this doesn't compile, since in a function with ` rethrows ` , only the call to
124
126
the passed in function that is marked as ` throws ` is allowed to throw.
0 commit comments