[swift-evolution] Protocol conformance error

Paul Cantrell cantrell at pobox.com
Wed Jan 17 13:38:50 CST 2018


Note that it would be sound for the language to allow the opposite, which is called “contravariance” (the more specific type takes a more general input):

    protocol A {}
    protocol B: A {}

    protocol C {
       func test(x: B)    // was A
    }

    class M: C {
       func test(x: A) {} // was B
    }

It could also allow covariant return types (the more specific type returns a more specific output):

    protocol C {
       func test() -> A
    }

    class M: C {
       func test() -> B {
          fatalError("just a stub")
       }
    }

Some languages support this, and Swift certainly could — though I don’t know that it’s a frequently request feature.

It would also be interesting if associated type constraints allowed this, which I don’t think they currently do:

    protocol C {
       associatedtype TestInput where B: TestInput   // error here

       func test(x: TestInput)
    }

Curiously, the following does not work, although it seems like it should:

    protocol A {}
    protocol B: A {}

    protocol C {
       associatedtype TestOutput: A

       func test() -> TestOutput
    }

    class M: C {
       func test() -> B {
          fatalError("just a stub")
       }
    }

It gives the error “inferred type 'B' (by matching requirement 'test()') is invalid: does not conform to ‘A’” even though B does conform to A. Huh.

Cheers, P


> On Jan 17, 2018, at 2:43 AM, Saagar Jha via swift-evolution <swift-evolution at swift.org> wrote:
> 
> If we have:
> 
> class N: A {}
> 
> you can pass an N into C’s test(x:), since N is an A, but not M’s test(x:), since N is not a B. Thus, it’s not a valid conformance.
> 
> Saagar Jha
> 
>> On Jan 17, 2018, at 00:04, Roshan via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>> 
>> Hi,
>> 
>> Cross posting from swift-users in case this behaviour isn't part of
>> the language and might be interesting to you folks.
>> 
>> Here is some sample code that gives a protocol conformance error in a
>> playground:
>> 
>> protocol A {}
>> protocol B: A {}
>> 
>> protocol C {
>>    func test(x: A)
>> }
>> 
>> class M: C {
>>    func test(x: B) {}
>> }
>> 
>> Is there a reason why the compiler doesn't infer that ((B) -> ())
>> matches ((A) -> ()) because of inheritance?
>> 
>> -- 
>> Warm regards
>> Roshan
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> 
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20180117/2e2095ea/attachment.html>


More information about the swift-evolution mailing list