In the example, I use use a typealias to override an associated type instead of a type constraint. It allows me to omit the typealias in the concrete type conforming to the protocol (the last declaration). If I use a same-type constraint as the warning suggests, then I have to explicitly declare the typealias in the concrete type, otherwise the compiler will complain that SpecificEndpoint doesn't implement StandardEndpoint.
I think this is a valid use-case, am I missing anything?
If it is, indeed, a valid use-case, is there anything I can do to silence the warning?
Should the compiler infer the typealias when using a same-type constraint?
protocol P { associatedtype A }
protocol P1: P { // first example
associatedtype A = Int
}
// or
protocol P1: P where A == Int {...} // second example
You won't have to explicitly declare A in conforming types.
However, the first example is a defaulting act – A is Int by default, but you can yet override it with a different type when conforming to a type:
class Foo: P1 {
typealias A = Bool
}
or default it to a different type when refining a protocol it inherits from:
protocol P2: P1 {
associatedtype A = String
}
The second example is an act of refining semantics (a same-type constraint), similar to how a read-only requirement inherited by a protocol can be redefined to be { get set }. Semantic refinements are irreversible (you can't revert the refinement in an inheriting protocol). A will be further constrained to Int. It is almost the same as using typealias A = Int.
However, even though a same-type constraint is supposed to define A once and for all, at present you can still default A to another type in an inheriting protocol. This seems to be a relatively serious semantic bug, since a second same-type constraint will naturally not be allowed by the compiler anywhere A appears down the hierarchy. SR-7336
protocol P { associatedtype A }
protocol P1: P {
func foo(_ arg: A)
}
extension P1 {
typealias A = Int
}
You are either overriding or shadowing A. In foo(_ arg: A), A will now be Int. This shouldn't be allowed and shadows the whole point of having an associated type and, moreover, is source breaking through retroactive extensions. In other words, it's a bug. Thanks for bringing up this topic!