Covariance in protocol adoption


(Diego Sánchez) #1

Hi all,

Covariance works properly with classes:

class MyType {}
class MySubtype: MyType {}
class MyClass {
    func createMyType() -> MyType {
        return MyType()
    }
}

class MySubClass: MyClass {
    override func createMyType() -> MySubtype {
        return MySubtype()
    }
}

However it doesn't work for protocol conformance:

protocol MyProtocol {
    func createMyType() -> MyType
}

class MyConformingClass: MyProtocol {
    func createMyType() -> MySubtype {
        return MySubtype()
    }
}

Compiler error for this case:
error: type 'MyConformingClass' does not conform to protocol 'MyProtocol'
note: protocol requires function 'createMyType()' with type '() -> MyType'
note: candidate has non-matching type '() -> MySubtype'

I know I can fix it by using associated objects in MyProtocol definition,
but then if I want to declare a property of type MyProtocol I have to go
dancing with generics everywhere.

Is this a known limitation/bug? Any plans to improve this?

Cheers,
Diego


(David Turnbull) #2

Swift 3.0 will bring many changes to protocols. I expect these issues will
be discussed a lot more once 2.2 is shipped.

-david

···

On Tue, Feb 16, 2016 at 11:54 AM, David Sweeris via swift-users < swift-users@swift.org> wrote:

I think it’s something to do with subclasses overriding the method and
potentially returning a type that’s different that what the compiler is
expecting. Or something like that.

I hope it gets addressed at some point, though, because it drives me nuts,
too.

On Feb 16, 2016, at 1:47 PM, Diego Sánchez via swift-users < > swift-users@swift.org> wrote:

Hi all,

Covariance works properly with classes:

class MyType {}
class MySubtype: MyType {}
class MyClass {
    func createMyType() -> MyType {
        return MyType()
    }
}

class MySubClass: MyClass {
    override func createMyType() -> MySubtype {
        return MySubtype()
    }
}

However it doesn't work for protocol conformance:

protocol MyProtocol {
    func createMyType() -> MyType
}

class MyConformingClass: MyProtocol {
    func createMyType() -> MySubtype {
        return MySubtype()
    }
}

Compiler error for this case:
error: type 'MyConformingClass' does not conform to protocol 'MyProtocol'
note: protocol requires function 'createMyType()' with type '() -> MyType'
note: candidate has non-matching type '() -> MySubtype'

I know I can fix it by using associated objects in MyProtocol definition,
but then if I want to declare a property of type MyProtocol I have to go
dancing with generics everywhere.

Is this a known limitation/bug? Any plans to improve this?

Cheers,
Diego

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


(Joe Groff) #3

Yeah, this is a known limitation we'd like to address some day.

-Joe

···

On Feb 16, 2016, at 11:47 AM, Diego Sánchez via swift-users <swift-users@swift.org> wrote:

Is this a known limitation/bug? Any plans to improve this?


(David Sweeris) #4

I think it’s something to do with subclasses overriding the method and potentially returning a type that’s different that what the compiler is expecting. Or something like that.

I hope it gets addressed at some point, though, because it drives me nuts, too.

···

On Feb 16, 2016, at 1:47 PM, Diego Sánchez via swift-users <swift-users@swift.org> wrote:

Hi all,

Covariance works properly with classes:
class MyType {}
class MySubtype: MyType {}

class MyClass {
    func createMyType() -> MyType {
        return MyType()
    }
}

class MySubClass: MyClass {
    override func createMyType() -> MySubtype {
        return MySubtype()
    }
}

However it doesn't work for protocol conformance:

protocol MyProtocol {
    func createMyType() -> MyType
}

class MyConformingClass: MyProtocol {
    func createMyType() -> MySubtype {
        return MySubtype()
    }
}

Compiler error for this case:
error: type 'MyConformingClass' does not conform to protocol 'MyProtocol'
note: protocol requires function 'createMyType()' with type '() -> MyType'
note: candidate has non-matching type '() -> MySubtype'

I know I can fix it by using associated objects in MyProtocol definition, but then if I want to declare a property of type MyProtocol I have to go dancing with generics everywhere.

Is this a known limitation/bug? Any plans to improve this?

Cheers,
Diego

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users