Getting rid of this “Typealias overriding associated type” warning?

This question is related to this and this thread.

This works but gives a Fix it-warning:

protocol IntegerStatusCode : RawRepresentable, ExpressibleByIntegerLiteral {
    // Typealias overriding associated type 'IntegerLiteralType' from protocol 'ExpressibleByIntegerLiteral' is better expressed as same-type constraint on the protocol
    typealias IntegerLiteralType = RawValue
    init(rawValue: RawValue)
}
extension IntegerStatusCode {
    init(integerLiteral value: IntegerLiteralType) { self.init(rawValue: value) }
}
    
struct StatusCode : IntegerStatusCode {
    let rawValue: Int
}

The goal is to not have to typealias in the conformer.
If I apply the fixit, the code looks better but does not compile:

protocol IntegerStatusCode : RawRepresentable, ExpressibleByIntegerLiteral where IntegerLiteralType == RawValue {
    init(rawValue: RawValue)
}
// Type 'StatusCode' does not conform to protocol 'ExpressibleByIntegerLiteral'

First of all, if I'm not mistaken these are not semantically identical. The fixit code ensures that the two associated types are always identical, while the original code does not.

The threads I linked to have me believe that typealias IntegerLiteralType = RawValue defines a default for the associated type, but does not impose any constraints upon the two associated types if the client wishes something else.

I also understood that the fixit doesn't compile because of inference limitations, and nothing else.

Since this code actually requires that the two associated types be identical, the right way to do it (that compiles) would be:

protocol IntegerStatusCode : RawRepresentable, ExpressibleByIntegerLiteral where Self.IntegerLiteralType == Self.RawValue {
    typealias IntegerLiteralType = RawValue
    init(rawValue: RawValue)
}
extension IntegerStatusCode {
    init(integerLiteral value: IntegerLiteralType) { self.init(rawValue: value) }
}

...where typealias IntegerLiteralType = RawValue is only necessary in order to assist inference. Is that right?

I'm wondering:

  • How should it be written to avoid the warning?
  • In the other threads I got the impression that using typealias in a protocol to provide default associated types was undesirable (it wasn't clear to me why), and that default values for associated types could be specified with a redeclaration using associatedtype in the sub-protocol to aid inference. When I do this in my example, it doesn't compile anymore (StatusCode does not conform to ExpressibleBy...). What did I misunderstand about that recommendation?

I'm using Xcode 11.3.1

Spot on, this is an associated type inference limitation. I'm afraid the best you can do for now to simulate a same-type constraint is to continue using the typealias and ignore the warning. I'll see if I can land a fix in the next couple weeks.

Thanks! As long as this is the recommended workaround and that I didn't misunderstand anything important the warning is not a problem.

It'd be nice if there were some way to tell when and where the inference engine has hit an artificial boundary. That way I wouldn't have to question my understanding of what I wrote, and could focus on helping it. Maybe that's not realistic though.

This particular one is just a bug, but we do have intentional limitations the compiler could indeed do a lot better in diagnosing (for example, the limitation of the scope of associated type inference to just the members of the protocol that introduces or restates the given associated type manifests itself as a plain conformance error).

Terms of Service

Privacy Policy

Cookie Policy