Search code examples
swiftprotocolsassociated-types

Protocol restriction on another protocol associated type


I have a protocol MyProtocol which has an associatedtype, inferred by the return type of myFunction

struct MyStruct: Codable {
    var myVar: Int
}

protocol MyProtocol {
    associatedtype MyType
    func myFunction()-> MyType
}

class MyClass1: MyProtocol {
    func myFunction()-> MyStruct? {
        return MyStruct(myVar: 1) //ex.
    }
}

class MyClass2: MyProtocol {
    func myFunction()-> Int? {
        return 1 // ex.
    }
}
  • In MyClass1, associatedtype is infered as MyStruct?
  • In MyClass2, associatedtype is infered as Int?

from there everything works fine. No I want to build another protocol that can only be applied to a MyProtocol if associatedtype is Codable :

protocol MyProtocolCodable where Self: MyProtocol, MyType == Codable? {}

the code runs fine until here but when I try to apply it to my class I get an error:

extension MyClass1: MyProtocolCodable{} 🛑

'MyProtocolCodable' requires the types 'MyStruct?' and 'Codable?' (aka 'Optional<Decodable & Encodable>') be equivalent

yet, as far as I can see MyStruct? (aka Optional) and Codable? (aka Optional<Decodable & Encodable>) are equivalent?

How can I get rid of this error message? Am I doing something that is not meant to be done?


Solution

  • As far as I can see MyStruct? (aka Optional) and Codable? (aka Optional<Decodable & Encodable>) are equivalent?

    No, they are not. MyStruct conforms to Codable but is not equivalent of it.

    As in: every MyStruct is Codable but not every Codable is MyStruct.


    You can try changing MyType == Codable? to MyType: Codable:

    protocol MyProtocolCodable where Self: MyProtocol, MyType: Codable {}
    

    as MyStruct is not equal to Codable?.