I am experimenting with protocols and generics. Stumbled upon this document:
# Protocol Types Cannot Conform to Protocols
In Swift, a protocol that does not have `Self` or associated type requirements can be used as a type. You can use a variable or constant of a protocol type, also called an __existential type__, to hold a value of any conforming type:
```swift
protocol Animal {
func makeNoise()
static var species: String { get }
}
struct Dog: Animal {
func makeNoise() { print("Woof") }
static var species: String = "Canus familiaris"
}
struct Cat: Animal {
func makeNoise() { print("Meow") }
static var species: String = "Felis catus"
}
var animal: Animal // `Animal` is used here as a type.
animal = Dog()
This file has been truncated. show original
Specifically this line
// error: protocol type 'Animal' cannot conform to 'Animal'...
This no longer applies, I can correctly compile and execute this code. Can someone please explain is the example no longer valid ? What exactly and when has it been introduced in the language to make this error disappear ?
1 Like
cukr
July 9, 2023, 11:56am
2
I believe it's because of Implicitly Opened Existentials
note that protocol types (aka existentials) still cannot conform to protocols (with the exception of Error
)
2 Likes
bbrk24
July 9, 2023, 12:42pm
3
Also, any protocols imported from Objective-C.
We should probably file an issue to revise this user doc to reflect the reduction in possible error surface now that implicitly-opened existentials are in.
3 Likes
Many thanks. Can you please guide me to understand how Error protocol conforms to itself ?
cukr
July 15, 2023, 12:37pm
6
It's a special case hardcoded into the compiler. I cannot guide you, because I don't know it myself - I'm just using the compiler, not developing it.
If you want to figure it out yourself, here's a PR adding that
apple:master
← rjmccall:error-self-conformance
opened 06:49AM - 16 Nov 18 UTC
Most of the foundation for this was laid in earlier patches.
This PR should n… ot be merged because it arguably requires Evolution approval.
I was considered adding an `-enable-error-self-conformance` flag and merging this so that people could test it. Unfortunately, testing it would require the stdlib to be built under that flag, and doing that by default would change the ABI of the stdlib — and avoiding that ABI change is exactly why I can't merge this patch yet. So no dice.
PRs this depends on that aren't in the 5.0 branch: #20658, #20662
1 Like
Many thanks @cukr . From practical standpoint I understand this lets me write
func genericError<T: Error>(error: T) {
print(error.localizedDescription)
}
var error: Error
genericError(error: error)
Why was this added for Error specifically ? Now that we have implicit open existentials this will work for other protocol types as well - does that mean that the compiler feature specific for the Error protocol no longer applies ?
cukr
July 15, 2023, 1:04pm
8
It was added to Error
specifically to enable you to write Result<Foo, Error>
mirroring a throwing function returning Foo
Existentials opening doesn't work here because you don't have anything to open in the success
case :(
# Add Result to the Standard Library
* Proposal: [SE-0235](0235-add-result.md)
* Author: [Jon Shier](https://github.com/jshier)
* Review Manager: [Chris Lattner](https://github.com/lattner)
* Status: **Implemented (Swift 5)**
* Implementation: [apple/swift#21073](https://github.com/apple/swift/pull/21073),
[apple/swift#21225](https://github.com/apple/swift/pull/21225),
[apple/swift#21378](https://github.com/apple/swift/pull/21378)
* Review: ([initial review](https://forums.swift.org/t/se-0235-add-result-to-the-standard-library/17752)) ([second review](https://forums.swift.org/t/revised-se-0235-add-result-to-the-standard-library/18371)) ([acceptance](https://forums.swift.org/t/accepted-with-modifications-se-0235-add-result-to-the-standard-library/18603))
## Introduction
Swift's current error-handling, using `throws`, `try`, and `catch`, offers automatic and synchronous handling of errors through explicit syntax and runtime behavior. However, it lacks the flexibility needed to cover all error propagation and handling in the language. `Result` is a type commonly used for manual propagation and handling of errors in other languages and within the Swift community. Therefore this proposal seeks to add such a type to the Swift standard library.
## Motivation
Swift's [Error Handling Rationale and Proposal](https://github.com/apple/swift/blob/master/docs/ErrorHandlingRationale.rst) document lays out the reasoning behind and high level details of the current Swift error handling story. Types conforming to `Error` can be propagated and handled using the `do` `try` `catch` `throw` syntax. The rationale document refers to this model as a typed and automatically propagating error system. However, this system has several drawbacks, some of which are mentioned in the rationale document. Namely, it cannot compose with asynchronous work, more complex error handling, or with failure values which don't conform to `Error`. The added flexibility of typed, marked, but manually propagating error type can address these shortcomings. Namely `Result<Value, Error>`.
## Proposed solution
This file has been truncated. show original
3 Likes