Status check: Typed throws

It’s great to see progress on typed throws! I have a few design points to consider that are not mentioned in the posts you linked.

Non-throwing error types

Both the proposal draft and the post from @John_McCall post seem to assume all non-throwing functions have error type of Never. This would be unfortunate. All functions with uninhabited error types should be considered non-throwing. This implies a tweak to John’s expression for computing a rethrown error type:

func foo<AError: Error, BError: Error>(a: () throws(AError) -> Int,
                                       b: () throws(BError) -> Int)
    throws(errorUnion(AError, BError) == Never ? Never : Error) -> Int

Becomes

func foo<AError: Error, BError: Error>(a: () throws(AError) -> Int,
                                       b: () throws(BError) -> Int)
    throws(errorUnion(AError, BError) == Never || AError is uninhabitable && BError is uninhabitable ? Never : Error) -> Int

This expression still leaves something to be desired: AError and BError may have a more specific common supertype than Error`. Ideally the compiler would be able to figure this out.

Typed rethrows

The fundamental semantic of rethrows is that a function can only throw when an argument actually throws. In the presence of typed errors, it should be possible to catch and transform errors before rethrowing. This implies it should be possible to write rethrows TransformedError regardless of the error types thrown by arguments. In such a function, the body would catch the errors thrown by its arguments and convert them to TransformedError.

The difference between throws SomeError and rethrows SomeError would be subtle but important. When writing rethrows SomeError it is only possible to throw if an argument first throws. The rethrows expression logic above would be modified slightly with the explicitly specified error type replacing Error (or the computed common supertype). Thus, rethrows SomeError may also be non-throwing depending on the arguments it receives.

Catch type inference

The proposal mentions that type inference for general catch clauses was omitted due to requiring breaking changes. Hopefully this could be included in Swift 6.

Opaque error types

It would be great if error types could be opaque just like return types. I didn’t see any mention of these in the proposal or John’s post and it seems like this feature interaction deserves consideration.

7 Likes