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!