[Pitch N+1] Typed Throws

Looks great.

Even though the implementation is quite non-trivial, all the rules and behaviours are intuitive and straightforward, which I think is a good sign that this is an elegant solution to a complex problem.

Multiple error types

I'm still very interested in the potential future expansion of this to better support throwing multiple types of errors, but I think the proposal as written stands well on its own and is clearly a big improvement even with those limitations. Plus, it still allows multi-type errors, just without syntactic conveniences (i.e. one will still have to manually define either union protocols or union enums, but at least it'll now be possible).

And I'm increasingly convinced (from discussion in Structural Sum Types (used to be Anonymous Union Types) and the proposal's succinct summary of the topic) that language-wide support for sum types is the best way to enable multi-typed throws anyway, which is technically orthogonal to this proposal and looks like it would compose naturally (requiring only a little error-specific support in the compiler, maybe, such as around exhaustiveness checking of catch statements).

AsyncIteratorProtocol

However, the suggested change to AsyncIteratorProtocol might not be able to be made in a manner that does not break ABI stability.

Is this implying this enhancement might not actually happen? If I recall correctly, the current position on ABI breakages is "no", even for Swift 6?

CancellationError

Maybe I missed it, but I didn't see the proposal mention how this will work with failable async sequences that also support cancellation? It should be called out, if indeed there is a problem there as others have suggested earlier in this thread.

It's still unclear to me how CancellationError is supposed to work in Swift, in general. Apple's own APIs don't use it consistently, and there's no apparent guidance on when or why it should be used vs just returning quietly. That lack of official clarity makes it hard to judge whether it's a flaw that the proposal would basically preclude the use of CancellationError in failable async sequences, or just by happenstance forcing a particular 'style'.

Effect on API resilience

I find this section a little hard to parse, because of the run-on sentences. Although if I pretend it's read aloud by Captain Kirk, it's at least entertaining. :grin:

Perhaps it could be written more simply and tersely, e.g.:

  • Favour (non-frozen) enums for your error types, as opposed to structs, so that you can add additional error cases in future.
  • Avoid use of typed errors in situations where errors are inherently unpredictable or beyond your control (e.g. app extension points / plug-in APIs).
  • Prefer opaque error types over concrete error types (e.g. throw some CustomErrorProtocol) if you need to ensure thrown errors have certain functionality, like a backtrace property, but it's not important to the caller what the specific error type is).
  • In libraries with Library Evolution enabled (resilient libraries) be particularly careful about using typed errors, and err on the side of not using them.