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 <[email protected]> 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
>> <[email protected] <mailto:[email protected]>> 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
>>> <[email protected] <mailto:[email protected]>> 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
>>> [email protected] <mailto:[email protected]>
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>
>> _______________________________________________
>> swift-evolution mailing list
>> [email protected] <mailto:[email protected]>
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution