swifterror-handlingpolymorphismprotocolsresulttype

Swift: Result's Failure Type cannot be protocol - "Type 'any ShadowError' cannot conform to Error"


Error is a protocol and one is able to do this...

let x: Result<Void, Error> = .success(())

ShadowError conforms to Error and is also a protocol yet one is not able to do this...

protocol ShadowError: Error {}
let x: Result<Void, ShadowError> = .success(()) // FAILS Type 'any ShadowError' cannot conform to Error

Because the compiler complains with this error

Type 'any ShadowError' cannot conform to Error

Is there anyway for the results Failure type be ShadowError (or other protocol)?


Solution

  • This is not possible as a protocol. You can make ShadowError an enum or a struct (even a struct that wraps another Error), but it a can't be a protocol. Protocol existentials ("any" instances of the protocol) do not conform to protocols, so any ShadowError is not an Error. There is one magical exception to this: any Error does conform to Error. But you can't reproduce that. It's only Error.

    For the docs on this, see SE-0235 Add Result to the Standard Library:

    As part of the preparatory work for this proposal, self-conformance was added for Error (and only Error). This is also generally useful for working with errors in a generic context.

    This self-conformance does not extend to protocol compositions including the Error protocol, only the exact type Error. It will be possible to add such compositions in the future, but that is out of scope for Swift 5.