[Pitch N+1] Typed Throws

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()
}
3 Likes