[Swift] Add support for 'is' and 'as' to check for conformance to protocols at runtime for non-@objc objects
| Originator: | AustinZheng | ||
| Number: | rdar://17833218 | Date Originated: | 7/28/2014 |
| Status: | Duplicate of 17328443 | Resolved: | |
| Product: | Developer Tools | Product Version: | |
| Classification: | Reproducible: |
Summary:
Right now, if you have a base protocol (e.g. BaseProtocol) and a bunch of protocols that extend that protocol (e.g. ProtocolA : BaseProtocol, ProtocolB : BaseProtocol, ProtocolC : BaseProtocol), you can create a variable or collection of type 'BaseProtocol' and then add instance(s) of objects that conform to ProtocolA, ProtocolB, or ProtocolC.
However, it's not possible to use the 'is' and 'as' operators to downcast objects in that variable or collection to the appropriate specific protocol type, *unless* the protocols are declared with @objc and the objects are @objc-compatible classes. This precludes the use of many of Swift's most powerful new features.
I want to propose that 'is' and 'as' should be extended to allow for checking for conformance with protocols and downcasting for all Swift objects, not just @objc classes. This would make composing types by using protocols far more effective.
Steps to Reproduce:
Run the following sample code in Xcode 6 DP 4 (either a playground or a simple command-line application):
// Example application
protocol BaseProtocol {
}
protocol ProtocolA : BaseProtocol {
func fooA()
}
protocol ProtocolB: BaseProtocol {
func fooB()
}
struct StructA : ProtocolA {
func fooA() { println("A") }
}
class ClassB : ProtocolB {
func fooB() { println("B") }
}
var myArray : [BaseProtocol] = [StructA(), StructA(), ClassB()]
for object in myArray {
switch object {
case let x as ProtocolA:
println("protocolA")
case let x as ProtocolB:
println("protocolB")
default:
println("none")
}
}
Expected Results:
Code compiles. At runtime "protocolA" and "protocolB" are printed out as appropriate, based on the contents of the array 'myArray'.
Actual Results:
Code does not compile. Error: "Cannot downcast from 'BaseProtocol' to non-@objc protocol type 'ProtocolA'"
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!
Looks like this was fixed in Swift 1.2; however, the referenced duplicate bug is still marked as 'Open'.