Xcode 7.2 beta 4 (7C62b) / Swift 2.1.1: Protocol with shorthand typealias is considered to have an associated type requirement

Originator:Karoly.Lorentey
Number:rdar://23687535 Date Originated:30-Nov-2015 03:46 PM
Status:Open Resolved:
Product:Developer Tools Product Version:Xcode (7C62b)
Classification:Other Bug Reproducible:Always
 
Summary:
It is sometimes convenient to define type aliases for types that are repeatedly used in an API. This can be useful for documenting the intended meaning of values of those types. Swift provides typealias to name complex types, and it comes handy in APIs like Source below:

struct Source<Value> {
    typealias Sink = Value -> Void
    func connect(sink: Sink) -> Connection { … }
}

Ideally, I would like to be able to provide these in protocols, too:

protocol SourceProtocol {
    typealias Value
    typealias Sink = Value -> Void
    func connect(sink: Sink) -> Connection
}

My intended meaning in this case is this:

protocol SourceProtocol {
    typealias Value
    func connect(sink: Value->Void) -> Connection
}

However, Swift 2.0 and 2.1.1 (as of Xcode 7.2 beta 4) ignores the defined value of SourceProtocol.Sink, and considers it an unbound type requirement, as if I wrote the following:

protocol SourceProtocol {
    typealias Value
    typealias Sink
    func connect(sink: Sink) -> Connection
}

This is surprising behavior — if shorthand type aliases cannot be supported in protocols, I’d strongly prefer the compiler to throw an error when encountering one rather than silently ignoring the parts after ’=’.

Steps to Reproduce:
Try compiling the following input:

protocol P {
    typealias V = Int   // (1)

    func foo(v: V)
}

struct S: P {   // (2)
    typealias V = String

    func foo(v: V) { }
}

let p: P = S() // (3)
p.foo(42)

Expected Results:
I expected that P.V is simply a shorthand for Int, so P is equivalent to the following:

protocol P { 
    func foo(v: Int)
}

This reading implies that P does not have an associated type requirement, and struct S does not conform to protocol P.
Thus, I expected the compiler to either
- complain that struct S does not conform to protocol P (error in line marked (2))
- or warn that shorthand typealiases aren’t supported in protocols (error in line marked (1))

Actual Results:
P.V is considered a fully generic associated type. The ’= Int’ clause is silently ignored. Thus, struct S is considered by the compiler to be conforming to it, and p’s declaration is rejected by the compiler:

repl.swift:13:8: error: protocol 'P' can only be used as a generic constraint because it has Self or associated type requirements
let p: P = S() // (3)
       ^
repl.swift:14:1: error: member 'foo' cannot be used on value of protocol type 'P'; use a generic constraint instead
p.foo(42)
^ ~~~

Regression:

Unknown

Notes:

Comments


Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!