How come this code:
protocol SomeProtocol {}
extension Int: SomeProtocol {}
func testA<T>(v: T) {
let protocolConformanceSuffix = v is SomeProtocol ? "yet v conforms to SomeProtocol!?" : "since v doesn't conform to SomeProtocol."
print(" testA: called version WITHOUT SomeProtocol constraint \(protocolConformanceSuffix)")
}
func testA<T: SomeProtocol>(v: T) {
print(" testA: called version WITH SomeProtocol constraint.")
}
func testB<T>(v: T) {
if v is SomeProtocol { print(" testB: v conforms to SomeProtocol, now calling testA ...") }
testA(v)
}
print("\nCalling testA(Float(1.2)):")
testA(Float(1.2))
print("\nCalling testA(1234):")
testA(1234)
print("\nCalling testB(1234):")
testB(1234)
produces the following output:
Calling testA(Float(1.2)):
testA: called version WITHOUT SomeProtocol constraint since v doesn't conform to SomeProtocol.
Calling testA(1234):
testA: called version WITH SomeProtocol constraint.
Calling testB(1234):
testB: v conforms to SomeProtocol, now calling testA ...
testA: called version WITHOUT SomeProtocol constraint yet v conforms to SomeProtocol!?
?
I would have expected calling testA through testB would be no different than calling testA directly, thus I'm surprised by the result of the last test, callling testB(1234).
Can someone please explain why testB(1234) results in a call to testA<T> rather than testA<T: SomeProtocol> even though the argument (1234) evidently conforms to SomeProtocol? The function is even able to say so itself.
(It's as if testB somehow removes the SomeProtocol conformance from v, even though it doesn't ... or it does it only statically and then it can be recovered/seen again at runtime ... but why should any of this need to be dynamic ... I'm not getting this.)
(Xcode7 beta 2)