Typealias overriding associated type not, in fact, better expressed as same-type constraint

What you want is expressible in two ways:

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

2 Likes