[swift-evolution] Protocol conformance error
Paul Cantrell
cantrell at pobox.com
Wed Jan 17 14:00:55 CST 2018
I remember discussions on this list of curious situations in which a protocol doesn’t even conform to itself. This may be related.
I’ll let others who better understand the type system and its limitations weigh in.
P
> On Jan 17, 2018, at 1:53 PM, Saagar Jha <saagar at saagarjha.com> wrote:
>
> Interestingly, it seems like Swift allows for contravariance for subclassing, in that this is valid code:
>
> protocol A {}
> protocol B: A {}
>
> class C { // Notice this is a class, not a protocol
> func test(x: B) {}
> }
>
> class M: C {
> func test(x: A) {}
> }
>
> Is it an oversight that this doesn’t apply to protocols?
>
> Saagar Jha
>
>> On Jan 17, 2018, at 11:38, Paul Cantrell <cantrell at pobox.com <mailto:cantrell at pobox.com>> wrote:
>>
>> 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 <mailto: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 <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>>
>>> _______________________________________________
>>> swift-evolution mailing list
>>> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>>> https://lists.swift.org/mailman/listinfo/swift-evolution <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/5c36a71f/attachment.html>
More information about the swift-evolution
mailing list