Type resolution/equality rules in protocol extensions (or: why does Swift give my associatedtype a default value?)

Consider the following code:

protocol Req {}

protocol ValueProvider {
    associatedtype Value: Req
    func getValue() -> Value
}


extension Never: Req {}

extension ValueProvider where Value == Never {
    func getValue() -> Never { // <-- this is the important line
        fatalError()
    }
}


struct S: ValueProvider {
    // intentionally empty
}

My assumption was that, since S neither defines a typealias for S.Value nor implements the getValue() function, S doesn't conform to the ValueProvider protocol and this would cause a compilation error.

However, this code compiles fine, and S.Value is somehow deduced as Never.

Question #1: Why does this compile? Why does Swift use Never as the default type for S.Value?

If I now change the marked line so that getValue()'s return type is Value instead of Never, the struct definition fails to compile and i get an "Type 'S' does not conform to protocol 'ValueProvider'" error message.
What is going on here?

Question #2: Why is there a difference between using Value and Never in a protocol extension with a Value == Never condition?

There is this post: What kind of magic behavior is this?. I believe it was intentional to infer the associated type this way, though some did say the type inference is unnecessarily aggressive.

Now sure how much has changed since then, though.

1 Like

Still an issue (while this claim is my personal opinion, not that from the core team).

Terms of Service

Privacy Policy

Cookie Policy