These two are not equivalent semantically (however it compiles being another matter), and this goes to the heart of what rethrows means in current Swift: rethrows means that f throws if and only if body throws—currently, there is no guarantee as to what f throws if body throws, but it throws something. By contrast, throws(E) means that f only throws E, but it might throw E de novo when body doesn't throw E, or body might throw E and f might not rethrow it.
// This example rethrows, but does not throw the same error as `body`:
func f(_ body: () throws -> Void) rethrows {
do {
try body()
} catch {
throw ErrorThatWrapsAnotherError(error)
}
}
// This example throws the same error as `body`, but does not rethrow:
func f<
E: ErrorProtocolThatRequiresInitWithNoParameters
>(_ body: () throws(E) -> Void) throws(E) {
// We never execute `body`; throw unconditionally instead.
throw E()
}