It's not necessary elsewhere.
protocol Protocol { }
struct Struct<T: Protocol> { }
func f<T>(_: Struct<T>) { }
typealias TypeAlias<T: Protocol> = Struct<T> // Why is `: Protocol` necessary?
It's not necessary elsewhere.
protocol Protocol { }
struct Struct<T: Protocol> { }
func f<T>(_: Struct<T>) { }
typealias TypeAlias<T: Protocol> = Struct<T> // Why is `: Protocol` necessary?
My guess is, because the T
in your type alias definition is a new generic parameter that has nothing to do with any previous declaration, and that you "pass" as a parameter to an existing type Struct
. To illustrate that, you can rename it to something else, say:
typealias TypeAlias<U: Protocol> = Struct<U>
Similarly, if you had a class and then a subclass, protocol conformance would be required:
class C<T: Protocol> { }
class D<U: Protocol>: C<U> { }
Like a lot of things in language design, the answer is “that’s just how it works”. There’s no deeper reason beyond what the implementation does.
The feature is called requirement inference, and it visits a handful of fixed positions when looking for requirements to infer in this manner.
Here is my explanation from a few months ago: Some inconsistency in Generic Type Parameter declaration - #6 by Slava_Pestov
Also see Section 11.1 of https://download.swift.org/docs/assets/generics.pdf.