[swift-users] question about covariant subtyping

Slava Pestov spestov at apple.com
Wed Feb 22 17:23:04 CST 2017


It looks intentional.

Function conversions can be performed on argument and return types that are related via ‘Subtype’ constraints in the constraint solver, however array conversions are only possible via the ‘Conversion’ relation.

Changing this would require some additional work in SILGen to support such function conversions.

Slava

> On Feb 22, 2017, at 3:06 PM, Joe Groff via swift-users <swift-users at swift.org> wrote:
> 
>> 
>> On Feb 22, 2017, at 8:50 AM, Michael Roitzsch via swift-users <swift-users at swift.org> wrote:
>> 
>> Hi all,
>> 
>> I am fairly new to Swift, so this may very well be a simple misunderstanding on my part.
>> 
>> I was exploring the subtyping rules of Swift, especially regarding covariance. I came across two examples where the outcome puzzles me and I would appreciate if someone could explain this to me.
>> 
>> First I tried the covariance for the standard container types. Here is an excerpt from a REPL session:
>> 
>> Michael at carpo:~ > swift
>> Welcome to Apple Swift version 3.0.2 (swiftlang-800.0.63 clang-800.0.42.1). Type :help for assistance.
>> 1> open class Super {}; class Sub: Super {}
>> 2> print([Sub()] is [Sub])
>> true
>> 3> print([Sub()] is [Super])
>> true
>> 4> print(Array<Sub>(arrayLiteral: Sub()) is [Sub])
>> true
>> 5> print(Array<Sub>(arrayLiteral: Sub()) is [Super])
>> error: repl.swift:5:39: error: 'Super' is not a subtype of 'Sub'
>> print(Array<Sub>(arrayLiteral: Sub()) is [Super])
>>     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~
>> 
>> Why does it matter for subtyping against [Super] whether I express an array as [Sub] or Array<Sub>(arrayLiteral: Sub())?
>> 
>> Then I tried combining array covariance with function argument type contravariance:
>> 
>> Michael at carpo:~ > swift
>> Welcome to Apple Swift version 3.0.2 (swiftlang-800.0.63 clang-800.0.42.1). Type :help for assistance.
>> 1> open class Super {}; class Sub: Super {}
>> 2> func f(_: [Super]) {}
>> 3> let test: ([Sub]) -> Void = f
>> error: repl.swift:3:29: error: cannot convert value of type '([Super]) -> ()' to specified type '([Sub]) -> Void'
>> let test: ([Sub]) -> Void = f
>>                           ^
>> 
>> Why is this assignment not possible? It works fine (as expected) when using plain Super and Sub instead of arrays.
> 
> Those are both bugs. There's no fundamental reason these should be errors.
> 
> -Joe
> _______________________________________________
> swift-users mailing list
> swift-users at swift.org <mailto:swift-users at swift.org>
> https://lists.swift.org/mailman/listinfo/swift-users <https://lists.swift.org/mailman/listinfo/swift-users>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-users/attachments/20170222/5452ae47/attachment.html>


More information about the swift-users mailing list