Synthesized Equatable conformance for Type

Hey,

I've a question concerning concerning the conformance to Equatable generated by the compiler for Type. I've run into a problem where the compiler doens't want to synthesize the conformance, and I don't understand why. Consider the example below:

import UIKit

protocol MyCell where Self: UITableViewCell {}

final class UserCell: UITableViewCell, MyCell {}

// ---

protocol MyCellViewModel: Equatable {
    var cellType: MyCell.Type { get }
}

struct UserCellViewModel: MyCellViewModel {
    let cellType: MyCell.Type = UserCell.self
}

With this code, the compiler emits the error: Type 'UserCellViewModel' does not conform to protocol 'Equatable'. Now, if I use a computed property for cellType, meaning UserCellViewModel becomes:

struct UserCellViewModel: MyCellViewModel {
    var cellType: MyCell.Type { UserCell.self }
}

The compiler is fine with that and can synthesize the conformance to Equatable. Somebody understand why? This seems related to Type because it works fine with URL, String, or whatever.

Metatypes can be compared using == but they don't conform to protocols, like Equatable. By having a stored property of type MyCell.Type (what MyCell is here doesn't actually matter), the compiler detects that you have a stored property that doesn't conform to Equatable and doesn't synthesize the implementation.

In your second example, you've "worked around" the problem by making it a computed property (which is ignored when determining whether to synthesize), but the synthesized implementation isn't comparing that property at all. If you do want it to, the synthesized implementation won't do the right thing.

4 Likes

To add to this, the error message should be improved once Swift 5.2 releases to express this more clearly. It will now say:

/Users/owenvoorhees/Desktop/hello.swift:13:8: error: type 'UserCellViewModel' does not conform to protocol 'Equatable'
struct UserCellViewModel: MyCellViewModel {
       ^
/Users/owenvoorhees/Desktop/hello.swift:14:9: note: stored property type 'MyCell.Type' does not conform to protocol 'Equatable', preventing synthesized conformance of 'UserCellViewModel' to 'Equatable'
    let cellType: MyCell.Type = UserCell.self
5 Likes

Thanks a lot for the explanation! And Iā€™m excited by the clearer error message in Swift v5.2 :slight_smile: .